diff --git a/.clang-tidy b/.clang-tidy index 82362cf..5e421cc 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,28 +1,25 @@ -Checks: > - readability-*, - modernize-*, - performance-*, - bugprone-unchecked-optional-access, - bugprone-sizeof-expression, - bugprone-suspicious-missing-comma, - bugprone-suspicious-index, - bugprone-undefined-memory-manipulation, - bugprone-use-after-move, - bugprone-out-of-bound-access, - -readability-identifier-length, - -readability-magic-numbers, - -bugprone-narrowing-conversions, - -performance-enum-size, - -performance-inefficient-string-concatenation, - -bugprone-integer-division, - -bugprone-easily-swappable-parameters, +Checks: + - readability-* + - modernize-* + - performance-* + - bugprone-* + - -readability-identifier-length + - -readability-magic-numbers + - -bugprone-integer-division + - -bugprone-easily-swappable-parameters + - -bugprone-narrowing-conversions + - -modernize-avoid-c-arrays,-warnings-as-errors WarningsAsErrors: '*' -# Solo incluir archivos de tu código fuente -HeaderFilterRegex: '^source/(sections|ui)/.*' +# Solo incluir archivos de tu código fuente (external tiene su propio .clang-tidy) +# Excluye los headers SPIR-V generados en rendering/sdl3gpu/ +HeaderFilterRegex: 'source/(?!external/|rendering/sdl3gpu/.*_spv\.h).*' FormatStyle: file CheckOptions: + # bugprone-empty-catch: aceptar catches vacíos marcados con @INTENTIONAL en un comentario + - { key: bugprone-empty-catch.IgnoreCatchWithKeywords, value: '@INTENTIONAL' } + # Variables locales en snake_case - { key: readability-identifier-naming.VariableCase, value: lower_case } @@ -43,7 +40,7 @@ CheckOptions: # Variables estáticas privadas como miembros privados - { key: readability-identifier-naming.StaticVariableCase, value: lower_case } - { key: readability-identifier-naming.StaticVariableSuffix, value: _ } - + # Constantes estáticas sin sufijo - { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE } @@ -80,4 +77,4 @@ CheckOptions: - { key: readability-identifier-naming.FunctionCase, value: camelBack } # Parámetros en lower_case - - { key: readability-identifier-naming.ParameterCase, value: lower_case } \ No newline at end of file + - { key: readability-identifier-naming.ParameterCase, value: lower_case } diff --git a/CMakeLists.txt b/CMakeLists.txt index 3aec2bf..ecdeec7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -243,6 +243,7 @@ set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAK find_program(CLANG_TIDY_EXE NAMES clang-tidy) find_program(CLANG_FORMAT_EXE NAMES clang-format) +find_program(CPPCHECK_EXE NAMES cppcheck) # Recopilar todos los archivos fuente, excluyendo external/ file(GLOB_RECURSE ALL_SOURCE_FILES @@ -252,6 +253,14 @@ file(GLOB_RECURSE ALL_SOURCE_FILES ) list(FILTER ALL_SOURCE_FILES EXCLUDE REGEX ".*/external/.*") +# Para cppcheck, pasar solo .cpp (los headers se procesan transitivamente). +# Si pasamos .hpp como TUs independientes, cppcheck reporta falsos positivos de +# 'unusedStructMember' porque no hace análisis cross-TU y ve miembros de clase +# cuyo uso vive en un .cpp distinto. +set(CPPCHECK_SOURCES ${ALL_SOURCE_FILES}) +list(FILTER CPPCHECK_SOURCES INCLUDE REGEX ".*\\.cpp$") +list(FILTER CPPCHECK_SOURCES EXCLUDE REGEX ".*_spv\\.h$") + # Targets de clang-tidy if(CLANG_TIDY_EXE) # En macOS con clang-tidy de Homebrew LLVM, es necesario pasar el sysroot @@ -308,3 +317,28 @@ if(CLANG_FORMAT_EXE) else() message(STATUS "clang-format no encontrado - targets 'format' y 'format-check' no disponibles") endif() + +# Targets de cppcheck +if(CPPCHECK_EXE) + add_custom_target(cppcheck + COMMAND ${CPPCHECK_EXE} + --enable=warning,style,performance,portability + --std=c++20 + --language=c++ + --inline-suppr + --suppress=missingIncludeSystem + --suppress=toomanyconfigs + -D_DEBUG + -DLINUX_BUILD + --quiet + -I ${CMAKE_SOURCE_DIR}/source + -I ${CMAKE_SOURCE_DIR}/source/external + -I ${CMAKE_SOURCE_DIR}/source/rendering + -I ${CMAKE_SOURCE_DIR}/source/rendering/sdl3gpu + ${CPPCHECK_SOURCES} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMENT "Running cppcheck..." + ) +else() + message(STATUS "cppcheck no encontrado - target 'cppcheck' no disponible") +endif() diff --git a/tools/linter/ccae.desktop b/release/arcade/ccae.desktop similarity index 100% rename from tools/linter/ccae.desktop rename to release/arcade/ccae.desktop diff --git a/tools/linter/no-overview-at-startup.desktop b/release/arcade/no-overview-at-startup.desktop similarity index 100% rename from tools/linter/no-overview-at-startup.desktop rename to release/arcade/no-overview-at-startup.desktop diff --git a/tools/linter/no-overview-at-startup.sh b/release/arcade/no-overview-at-startup.sh similarity index 100% rename from tools/linter/no-overview-at-startup.sh rename to release/arcade/no-overview-at-startup.sh diff --git a/tools/linter/splash.png b/release/arcade/splash.png similarity index 100% rename from tools/linter/splash.png rename to release/arcade/splash.png diff --git a/tools/linter/splash.txt b/release/arcade/splash.txt similarity index 100% rename from tools/linter/splash.txt rename to release/arcade/splash.txt diff --git a/source/ui/service_menu.cpp b/source/ui/service_menu.cpp index c1d3c68..8657eb3 100644 --- a/source/ui/service_menu.cpp +++ b/source/ui/service_menu.cpp @@ -365,14 +365,15 @@ void ServiceMenu::initializeOptions() { // Shader: Desactivat / PostFX / CrtPi { - const std::string DISABLED_TEXT = Lang::getText("[SERVICE_MENU] SHADER_DISABLED"); - std::vector shader_values = {DISABLED_TEXT, "PostFX", "CrtPi"}; - auto shader_getter = [DISABLED_TEXT]() -> std::string { - if (!Options::video.shader.enabled) { return DISABLED_TEXT; } + std::string disabled_text = Lang::getText("[SERVICE_MENU] SHADER_DISABLED"); + std::vector shader_values = {disabled_text, "PostFX", "CrtPi"}; + auto shader_getter = [disabled_text]() -> std::string { + // NOLINTNEXTLINE(performance-no-automatic-move) -- captura por valor en lambda const, no se puede mover + if (!Options::video.shader.enabled) { return disabled_text; } return (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI) ? "CrtPi" : "PostFX"; }; - auto shader_setter = [DISABLED_TEXT](const std::string& val) { - if (val == DISABLED_TEXT) { + auto shader_setter = [disabled_text](const std::string& val) { + if (val == disabled_text) { Options::video.shader.enabled = false; } else { Options::video.shader.enabled = true; diff --git a/source/ui/service_menu.hpp b/source/ui/service_menu.hpp index 8371bb6..0ea7596 100644 --- a/source/ui/service_menu.hpp +++ b/source/ui/service_menu.hpp @@ -3,6 +3,7 @@ #include // Para SDL_Event #include // Para size_t +#include // Para std::uint8_t #include // Para function #include // Para pair #include // Para unique_ptr @@ -19,7 +20,7 @@ class MenuRenderer; class ServiceMenu { public: // --- Enums y constantes --- - enum class SettingsGroup { + enum class SettingsGroup : std::uint8_t { CONTROLS, VIDEO, AUDIO, @@ -27,7 +28,7 @@ class ServiceMenu { SYSTEM, MAIN }; - enum class GroupAlignment { + enum class GroupAlignment : std::uint8_t { CENTERED, LEFT }; diff --git a/source/ui/window_message.hpp b/source/ui/window_message.hpp index 198a4fd..879ce58 100644 --- a/source/ui/window_message.hpp +++ b/source/ui/window_message.hpp @@ -3,6 +3,7 @@ #include // Para SDL_FPoint, SDL_FRect #include // Para min +#include // Para std::uint8_t #include // Para allocator, shared_ptr #include // Para string #include // Para vector @@ -13,7 +14,7 @@ class WindowMessage { public: - enum class PositionMode { + enum class PositionMode : std::uint8_t { CENTERED, // La ventana se centra en el punto especificado FIXED // La esquina superior izquierda coincide con el punto }; @@ -176,7 +177,7 @@ class WindowMessage { // Animación de mostrar/ocultar struct ShowHideAnimation { - enum class Type { NONE, + enum class Type : std::uint8_t { NONE, SHOWING, HIDING }; diff --git a/source/utils.cpp b/source/utils.cpp index 281df7c..033a79b 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -1,3 +1,4 @@ +// NOLINTNEXTLINE(bugprone-reserved-identifier) -- requerido por para exponer M_PI en MSVC #define _USE_MATH_DEFINES #include "utils.hpp" diff --git a/tools/linter/build_time_tracker.sh b/tools/linter/build_time_tracker.sh deleted file mode 100755 index 871de68..0000000 --- a/tools/linter/build_time_tracker.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -SECONDS=0 -make linux_debug -duration=$SECONDS -echo "$((duration / 60)) minutes and $((duration % 60)) seconds elapsed." diff --git a/tools/linter/check_all_includes.sh b/tools/linter/check_all_includes.sh deleted file mode 100755 index 2670b74..0000000 --- a/tools/linter/check_all_includes.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -SOURCEPATH=../source/ - -for i in "$SOURCEPATH"/*.cpp -do - include-what-you-use -D _DEBUG -std=c++20 -Wall "$i" -done diff --git a/tools/linter/check_all_includes_with_pause.sh b/tools/linter/check_all_includes_with_pause.sh deleted file mode 100755 index 84cc83d..0000000 --- a/tools/linter/check_all_includes_with_pause.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -SOURCEPATH=../source/ - -for i in "$SOURCEPATH"/*.cpp -do - include-what-you-use -D DEBUG -std=c++20 -Wall "$i" - read -r -p "Presiona cualquier tecla para continuar..." - clear -done diff --git a/tools/linter/check_one_file_includes.sh b/tools/linter/check_one_file_includes.sh deleted file mode 100755 index 13c5aa5..0000000 --- a/tools/linter/check_one_file_includes.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -# Verifica que se haya proporcionado un archivo como argumento -if [ $# -eq 0 ]; then - echo "Uso: $0 " - exit 1 -fi - -FILE="$1" - -include-what-you-use -D _DEBUG -std=c++20 -Wall "$FILE" \ --I../source \ --Xiwyu --mapping_file=sdl3_mapping.imp \ --Xiwyu --update_comments \ --Xiwyu --verbose=3 \ No newline at end of file diff --git a/tools/linter/com_usar_clang-tidy.txt b/tools/linter/com_usar_clang-tidy.txt deleted file mode 100644 index 349450f..0000000 --- a/tools/linter/com_usar_clang-tidy.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Per a un fitxer, desde l'arrel del projecte executar: -clang-tidy source/fitxer.cpp -p build/ --fix - -# Per a varios fitxers, desde l'arrel: -find source/ \( -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) | \ -xargs -P4 -I{} bash -c 'echo "Procesando: {}"; clang-tidy {} -p build/ --fix' - - diff --git a/tools/linter/cppcheck_suppressions b/tools/linter/cppcheck_suppressions deleted file mode 100644 index 55ab5a8..0000000 --- a/tools/linter/cppcheck_suppressions +++ /dev/null @@ -1,8 +0,0 @@ -*:/home/sergio/gitea/coffee_crisis_arcade_edition/source/stb* -*:/home/sergio/gitea/coffee_crisis_arcade_edition/source/gif.c -*:/home/sergio/gitea/coffee_crisis_arcade_edition/source/jail* -*:/usr/include/* -*:../source/stb* -*:../source/gif.c -*:../source/jail* -*:/usr/include/* \ No newline at end of file diff --git a/tools/linter/generate_compile_commands_json.sh b/tools/linter/generate_compile_commands_json.sh deleted file mode 100755 index 0bc4903..0000000 --- a/tools/linter/generate_compile_commands_json.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -# 🏁 Ruta base del proyecto -BASE_DIR="/home/sergio/gitea/coffee_crisis_arcade_edition" - -# 📁 Ruta al build -BUILD_DIR="$BASE_DIR/build" - -# 📄 Archivo de mapping personalizado -MAPPING_FILE="$BASE_DIR/linux_utils/sdl3_mapping.imp" - -# 📦 Generar compile_commands.json -echo "🔧 Generando compile_commands.json..." -cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -S "$BASE_DIR" -B "$BUILD_DIR" - diff --git a/tools/linter/iwyu_tool.py b/tools/linter/iwyu_tool.py deleted file mode 100755 index 8aa4c7b..0000000 --- a/tools/linter/iwyu_tool.py +++ /dev/null @@ -1,553 +0,0 @@ -#!/usr/bin/env python3 - -##===--- iwyu_tool.py -----------------------------------------------------===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -""" Driver to consume a Clang compilation database and invoke IWYU. - -Example usage with CMake: - - # Unix systems - $ mkdir build && cd build - $ CC="clang" CXX="clang++" cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ... - $ iwyu_tool.py -p . - - # Windows systems - $ mkdir build && cd build - $ cmake -DCMAKE_CXX_COMPILER="%VCINSTALLDIR%/bin/cl.exe" \ - -DCMAKE_C_COMPILER="%VCINSTALLDIR%/VC/bin/cl.exe" \ - -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ - -G Ninja ... - $ python3 iwyu_tool.py -p . - -See iwyu_tool.py -h for more details on command-line arguments. -""" -from __future__ import print_function -import os -import re -import sys -import json -import time -import shlex -import shutil -import argparse -import tempfile -import subprocess - - -CORRECT_RE = re.compile(r'^\((.*?) has correct #includes/fwd-decls\)$') -SHOULD_ADD_RE = re.compile(r'^(.*?) should add these lines:$') -ADD_RE = re.compile('^(.*?) +// (.*)$') -SHOULD_REMOVE_RE = re.compile(r'^(.*?) should remove these lines:$') -FULL_LIST_RE = re.compile(r'The full include-list for (.*?):$') -END_RE = re.compile(r'^---$') -LINES_RE = re.compile(r'^- (.*?) // lines ([0-9]+)-[0-9]+$') - - -GENERAL, ADD, REMOVE, LIST = range(4) - - -def clang_formatter(output, style): - """ Process iwyu's output into something clang-like. """ - formatted = [] - - state = (GENERAL, None) - for line in output.splitlines(): - match = CORRECT_RE.match(line) - if match: - # See PR#1806 for more info - continue - match = SHOULD_ADD_RE.match(line) - if match: - state = (ADD, match.group(1)) - continue - match = SHOULD_REMOVE_RE.match(line) - if match: - state = (REMOVE, match.group(1)) - continue - match = FULL_LIST_RE.match(line) - if match: - state = (LIST, match.group(1)) - elif END_RE.match(line): - state = (GENERAL, None) - elif not line.strip(): - continue - elif state[0] == GENERAL: - formatted.append(line) - elif state[0] == ADD: - match = ADD_RE.match(line) - if match: - formatted.append("%s:1:1: %s: add '%s' (%s)" % - (state[1], - style, - match.group(1), - match.group(2))) - else: - formatted.append("%s:1:1: %s: add '%s'" % - (state[1], style, line)) - elif state[0] == REMOVE: - match = LINES_RE.match(line) - line_no = match.group(2) if match else '1' - formatted.append("%s:%s:1: %s: superfluous '%s'" % - (state[1], line_no, style, match.group(1))) - - return os.linesep.join(formatted) - - -DEFAULT_FORMAT = 'iwyu' -FORMATTERS = { - 'iwyu': lambda output: output, - 'clang': lambda output: clang_formatter(output, style="error"), - 'clang-warning': lambda output: clang_formatter(output, style="warning"), -} - - -if sys.platform.startswith('win'): - # Case-insensitive match on Windows - def normcase(s): - return s.lower() -else: - def normcase(s): - return s - - -def is_subpath_of(path, parent): - """ Return True if path is equal to or fully contained within parent. - - Assumes both paths are canonicalized with os.path.realpath. - """ - parent = normcase(parent) - path = normcase(path) - - if path == parent: - return True - - if not path.startswith(parent): - return False - - # Now we know parent is a prefix of path, but they only share lineage if the - # difference between them starts with a path separator, e.g. /a/b/c/file - # is not a parent of /a/b/c/file.cpp, but /a/b/c and /a/b/c/ are. - parent = parent.rstrip(os.path.sep) - suffix = path[len(parent):] - return suffix.startswith(os.path.sep) - - -def is_msvc_driver(compile_command): - """ Return True if compile_command matches an MSVC CL-style driver. """ - compile_command = normcase(compile_command) - - if compile_command.endswith('cl.exe'): - # Native MSVC compiler or clang-cl.exe - return True - - if compile_command.endswith('clang-cl'): - # Cross clang-cl on non-Windows - return True - - return False - - -def win_split(cmdline): - """ Minimal implementation of shlex.split for Windows following - https://msdn.microsoft.com/en-us/library/windows/desktop/17w5ykft.aspx. - """ - def split_iter(cmdline): - in_quotes = False - backslashes = 0 - arg = '' - for c in cmdline: - if c == '\\': - # MSDN: Backslashes are interpreted literally, unless they - # immediately precede a double quotation mark. - # Buffer them until we know what comes next. - backslashes += 1 - elif c == '"': - # Quotes can either be an escaped quote or the start of a quoted - # string. Paraphrasing MSDN: - # Before quotes, place one backslash in the arg for every pair - # of leading backslashes. If the number of backslashes is odd, - # retain the double quotation mark, otherwise interpret it as a - # string delimiter and switch state. - arg += '\\' * (backslashes // 2) - if backslashes % 2 == 1: - arg += c - else: - in_quotes = not in_quotes - backslashes = 0 - elif c in (' ', '\t') and not in_quotes: - # MSDN: Arguments are delimited by white space, which is either - # a space or a tab [but only outside of a string]. - # Flush any buffered backslashes and yield arg, unless empty. - arg += '\\' * backslashes - if arg: - yield arg - arg = '' - backslashes = 0 - else: - # Flush buffered backslashes and append. - arg += '\\' * backslashes - arg += c - backslashes = 0 - - if arg: - arg += '\\' * backslashes - yield arg - - return list(split_iter(cmdline)) - - -def split_command(cmdstr): - """ Split a command string into a list, respecting shell quoting. """ - if sys.platform.startswith('win'): - # shlex.split does not work for Windows command-lines, so special-case - # to our own implementation. - cmd = win_split(cmdstr) - else: - cmd = shlex.split(cmdstr) - - return cmd - - -def find_include_what_you_use(): - """ Find IWYU executable and return its full pathname. """ - env_iwyu_path = os.environ.get('IWYU_BINARY') - if env_iwyu_path: - return os.path.realpath(env_iwyu_path) - - # Search in same dir as this script. - iwyu_path = shutil.which('include-what-you-use', - path=os.path.dirname(__file__)) - if iwyu_path: - return os.path.realpath(iwyu_path) - - # Search the system PATH. - iwyu_path = shutil.which('include-what-you-use') - if iwyu_path: - return os.path.realpath(iwyu_path) - - return None - - -IWYU_EXECUTABLE = find_include_what_you_use() - - -class Process(object): - """ Manages an IWYU process in flight """ - def __init__(self, proc, outfile): - self.proc = proc - self.outfile = outfile - self.output = None - - def poll(self): - """ Return the exit code if the process has completed, None otherwise. - """ - return self.proc.poll() - - @property - def returncode(self): - return self.proc.returncode - - def get_output(self): - """ Return stdout+stderr output of the process. - - This call blocks until the process is complete, then returns the output. - """ - if not self.output: - self.proc.wait() - self.outfile.seek(0) - self.output = self.outfile.read().decode("utf-8") - self.outfile.close() - - return self.output - - @classmethod - def start(cls, invocation): - """ Start a Process for the invocation and capture stdout+stderr. """ - outfile = tempfile.TemporaryFile(prefix='iwyu') - process = subprocess.Popen( - invocation.command, - cwd=invocation.cwd, - stdout=outfile, - stderr=subprocess.STDOUT) - return cls(process, outfile) - - -KNOWN_COMPILER_WRAPPERS=frozenset([ - "ccache" -]) - - -class Invocation(object): - """ Holds arguments of an IWYU invocation. """ - def __init__(self, command, cwd): - self.command = command - self.cwd = cwd - - def __str__(self): - return ' '.join(self.command) - - @classmethod - def from_compile_command(cls, entry, extra_args): - """ Parse a JSON compilation database entry into new Invocation. """ - if 'arguments' in entry: - # arguments is a command-line in list form. - command = entry['arguments'] - elif 'command' in entry: - # command is a command-line in string form, split to list. - command = split_command(entry['command']) - else: - raise ValueError('Invalid compilation database entry: %s' % entry) - - if command[0] in KNOWN_COMPILER_WRAPPERS: - # Remove the compiler wrapper from the command. - command = command[1:] - - # Rewrite the compile command for IWYU - compile_command, compile_args = command[0], command[1:] - if is_msvc_driver(compile_command): - # If the compiler is cl-compatible, let IWYU be cl-compatible. - extra_args = ['--driver-mode=cl'] + extra_args - - command = [IWYU_EXECUTABLE] + extra_args + compile_args - return cls(command, entry['directory']) - - def start(self, verbose): - """ Run invocation and collect output. """ - if verbose: - print('# %s' % self, file=sys.stderr) - - return Process.start(self) - - -def fixup_compilation_db(compilation_db): - """ Canonicalize paths in JSON compilation database. """ - for entry in compilation_db: - # Convert relative paths to absolute ones if possible, based on the entry's directory. - if 'directory' in entry and not os.path.isabs(entry['file']): - entry['file'] = os.path.join(entry['directory'], entry['file']) - - # Expand relative paths and symlinks - entry['file'] = os.path.realpath(entry['file']) - - return compilation_db - - -def select_compilation_db(compilation_db, selection): - """ Return a new compilation database reduced to the paths in selection. """ - if not selection: - return compilation_db - - # Canonicalize selection paths to match compilation database. - selection = [os.path.realpath(p) for p in selection] - - new_db = [] - for path in selection: - if not os.path.exists(path): - print('warning: \'%s\' not found on disk.' % path, file=sys.stderr) - continue - - found = [e for e in compilation_db if is_subpath_of(e['file'], path)] - if not found: - print('warning: \'%s\' not found in compilation database.' % path, - file=sys.stderr) - continue - - new_db.extend(found) - - return new_db - -def slice_compilation_db(compilation_db, selection, exclude): - """ Return a new compilation database with filtered entries. """ - - new_db = select_compilation_db(compilation_db, selection) - - # Canonicalize selection paths to match compilation database. - exclude = [os.path.realpath(p) for p in exclude] - - for path in exclude: - if not os.path.exists(path): - print('warning: excluded path \'%s\' not found on disk.' % path, - file=sys.stderr) - continue - - new_db = [e for e in new_db if not is_subpath_of(e['file'], path)] - - return new_db - - -def worst_exit_code(worst, cur): - """Return the most extreme exit code of two. - - Negative exit codes occur if the program exits due to a signal (Unix) or - structured exception (Windows). If we've seen a negative one before, keep - it, as it usually indicates a critical error. - - Otherwise return the biggest positive exit code. - """ - if cur < 0: - # Negative results take precedence, return the minimum - return min(worst, cur) - elif worst < 0: - # We know cur is non-negative, negative worst must be minimum - return worst - else: - # We know neither are negative, return the maximum - return max(worst, cur) - - -def execute(invocations, verbose, formatter, jobs, max_load_average=0): - """ Launch processes described by invocations. """ - exit_code = 0 - if jobs == 1: - for invocation in invocations: - proc = invocation.start(verbose) - print(formatter(proc.get_output())) - exit_code = worst_exit_code(exit_code, proc.returncode) - return exit_code - - pending = [] - while invocations or pending: - # Collect completed IWYU processes and print results. - complete = [proc for proc in pending if proc.poll() is not None] - for proc in complete: - pending.remove(proc) - print(formatter(proc.get_output())) - exit_code = worst_exit_code(exit_code, proc.returncode) - - # Schedule new processes if there's room. - capacity = jobs - len(pending) - - if max_load_average > 0: - one_min_load_average, _, _ = os.getloadavg() - load_capacity = max_load_average - one_min_load_average - if load_capacity < 0: - load_capacity = 0 - if load_capacity < capacity: - capacity = int(load_capacity) - if not capacity and not pending: - # Ensure there is at least one job running. - capacity = 1 - - pending.extend(i.start(verbose) for i in invocations[:capacity]) - invocations = invocations[capacity:] - - # Yield CPU. - time.sleep(0.0001) - return exit_code - - -def main(compilation_db_path, source_files, exclude, verbose, formatter, jobs, - max_load_average, extra_args): - """ Entry point. """ - - if not IWYU_EXECUTABLE: - print('error: include-what-you-use executable not found', - file=sys.stderr) - return 1 - - try: - if os.path.isdir(compilation_db_path): - compilation_db_path = os.path.join(compilation_db_path, - 'compile_commands.json') - - # Read compilation db from disk. - compilation_db_path = os.path.realpath(compilation_db_path) - with open(compilation_db_path, 'r') as fileobj: - compilation_db = json.load(fileobj) - except IOError as why: - print('error: failed to parse compilation database: %s' % why, - file=sys.stderr) - return 1 - - compilation_db = fixup_compilation_db(compilation_db) - compilation_db = slice_compilation_db(compilation_db, source_files, exclude) - - # Transform compilation db entries into a list of IWYU invocations. - invocations = [ - Invocation.from_compile_command(e, extra_args) for e in compilation_db - ] - - return execute(invocations, verbose, formatter, jobs, max_load_average) - - -def _bootstrap(sys_argv): - """ Parse arguments and dispatch to main(). """ - - # This hackery is necessary to add the forwarded IWYU args to the - # usage and help strings. - def customize_usage(parser): - """ Rewrite the parser's format_usage. """ - original_format_usage = parser.format_usage - parser.format_usage = lambda: original_format_usage().rstrip() + \ - ' -- []' + os.linesep - - def customize_help(parser): - """ Rewrite the parser's format_help. """ - original_format_help = parser.format_help - - def custom_help(): - """ Customized help string, calls the adjusted format_usage. """ - helpmsg = original_format_help() - helplines = helpmsg.splitlines() - helplines[0] = parser.format_usage().rstrip() - return os.linesep.join(helplines) + os.linesep - - parser.format_help = custom_help - - # Parse arguments. - parser = argparse.ArgumentParser( - description='Include-what-you-use compilation database driver.', - epilog='Assumes include-what-you-use is available on the PATH.') - customize_usage(parser) - customize_help(parser) - - parser.add_argument('-v', '--verbose', action='store_true', - help='Print IWYU commands') - parser.add_argument('-o', '--output-format', type=str, - choices=FORMATTERS.keys(), default=DEFAULT_FORMAT, - help='Output format (default: %s)' % DEFAULT_FORMAT) - parser.add_argument('-j', '--jobs', type=int, default=1, - nargs='?', const=0, - help=('Number of concurrent subprocesses. If zero, ' - 'will try to match the logical cores of the ' - 'system.')) - parser.add_argument('-l', '--load', type=float, default=0, - help=('Do not start new jobs if the 1min load average ' - 'is greater than the provided value')) - parser.add_argument('-p', metavar='', required=True, - help='Compilation database path', dest='dbpath') - parser.add_argument('-e', '--exclude', action='append', default=[], - help=('Do not run IWYU on source files (or directories) ' - 'below this path.')) - parser.add_argument('source', nargs='*', - help=('Zero or more source files (or directories) to ' - 'run IWYU on. Defaults to all in compilation ' - 'database.')) - - def partition_args(argv): - """ Split around '--' into driver args and IWYU args. """ - try: - double_dash = argv.index('--') - return argv[:double_dash], argv[double_dash+1:] - except ValueError: - return argv, [] - argv, extra_args = partition_args(sys_argv[1:]) - args = parser.parse_args(argv) - - jobs = args.jobs - if jobs == 0: - jobs = os.cpu_count() or 1 - - return main(args.dbpath, args.source, args.exclude, args.verbose, - FORMATTERS[args.output_format], jobs, args.load, extra_args) - - -if __name__ == '__main__': - sys.exit(_bootstrap(sys.argv)) diff --git a/tools/linter/run_clang-tidy.sh b/tools/linter/run_clang-tidy.sh deleted file mode 100755 index 233ab9f..0000000 --- a/tools/linter/run_clang-tidy.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash - -# Script para ejecutar clang-tidy en múltiples directorios -# Uso: ./run_clang-tidy.sh [--fix] -# --fix: Aplica las correcciones automáticamente (opcional) - -# Detectar si se pasó el parámetro --fix -FIX_FLAG="" -if [[ "$1" == "--fix" ]]; then - FIX_FLAG="--fix" - echo "Modo: Aplicando correcciones automáticamente (--fix)" -else - echo "Modo: Solo análisis (sin --fix)" -fi -echo - -# Lista de rutas donde ejecutar clang-tidy -PATHS=( - "/home/sergio/gitea/coffee_crisis_arcade_edition/source" - "/home/sergio/gitea/coffee_crisis_arcade_edition/source/rendering" - "/home/sergio/gitea/coffee_crisis_arcade_edition/source/rendering/opengl" - "/home/sergio/gitea/coffee_crisis_arcade_edition/source/sections" - "/home/sergio/gitea/coffee_crisis_arcade_edition/source/ui" -) - -# Ruta del directorio build (relativa desde donde se ejecuta el script) -BUILD_DIR="/home/sergio/gitea/coffee_crisis_arcade_edition/build/" - -# Función para procesar un directorio -process_directory() { - local dir="$1" - - echo "=== Procesando directorio: $dir ===" - - # Verificar que el directorio existe - if [[ ! -d "$dir" ]]; then - echo "Error: El directorio $dir no existe" - return 1 - fi - - # Cambiar al directorio y ejecutar find con -maxdepth 1 para un solo nivel - cd "$dir" || return 1 - - # Buscar archivos .cpp, .h, .hpp solo en el nivel actual (no subdirectorios) - find . -maxdepth 1 \( -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) -print0 | \ - xargs -0 -P4 -I{} bash -c 'echo "Procesando: {}"; clang-tidy {} -p '"$BUILD_DIR"' '"$FIX_FLAG" - - echo "=== Completado: $dir ===" - echo -} - -# Procesar cada directorio en la lista -for path in "${PATHS[@]}"; do - process_directory "$path" -done - -echo "¡Proceso completado para todos los directorios!" diff --git a/tools/linter/run_cppcheck.sh b/tools/linter/run_cppcheck.sh deleted file mode 100755 index 48327a7..0000000 --- a/tools/linter/run_cppcheck.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash - -# Función para mostrar el uso del script -mostrar_uso() { - echo "Uso: $0 [-o opción]" - echo "Opciones:" - echo " w Ejecutar cppcheck con warning, style, performance" - echo " a Ejecutar cppcheck con todas las opciones habilitadas" - echo " u Ejecutar cppcheck para unusedFunction" -} - -# Inicializar las variables -opcion="" - -# Procesar las opciones -while getopts "o:" opt; do - case $opt in - o) - opcion=$OPTARG - ;; - *) - mostrar_uso - exit 1 - ;; - esac -done - -# Ejecutar según la opción seleccionada -case $opcion in - w) - cppcheck --force --enable=warning,style,performance --std=c++20 \ - --check-level=exhaustive \ - --suppressions-list=./cppcheck_suppressions \ - ../source/ \ - 2>./cppcheck-result-warning-style-performance.txt - ;; - a) - cppcheck --force --enable=all -I /usr/include --std=c++20 \ - --suppress=missingIncludeSystem \ - --suppressions-list=./cppcheck_suppressions \ - ../source/ \ - 2>./cppcheck-result-all.txt - ;; - u) - cppcheck --enable=style --std=c++20 \ - --suppressions-list=./cppcheck_suppressions \ - ../source/ \ - 2>./cppcheck-result-unusedFunction.txt - ;; - *) - mostrar_uso - exit 1 - ;; -esac diff --git a/tools/linter/run_iwyu.sh b/tools/linter/run_iwyu.sh deleted file mode 100755 index aa02e58..0000000 --- a/tools/linter/run_iwyu.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -# 🏁 Ruta base del proyecto -BASE_DIR="/home/sergio/gitea/coffee_crisis_arcade_edition" - -# 📁 Ruta al build -BUILD_DIR="$BASE_DIR/build" - -# 📄 Archivo de mapping personalizado -MAPPING_FILE="$BASE_DIR/linux_utils/sdl3_mapping.imp" - -# 📦 Generar compile_commands.json -echo "🔧 Generando compile_commands.json..." -cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -S "$BASE_DIR" -B "$BUILD_DIR" - -# 🛠️ Ejecutar IWYU con fix_includes.py -echo "🚀 Ejecutando IWYU..." -./iwyu_tool.py -p "$BUILD_DIR" -- -Xiwyu --mapping_file="$MAPPING_FILE" -Xiwyu --verbose=3 \ -| fix_include --update_comments --reorder --nosafe_headers - -# 🧹 Reemplazar // for por // Para en líneas de #include -echo "✍️ Corrigiendo comentarios en includes..." -find "$BASE_DIR" -type f \( -name "*.cpp" -o -name "*.h" \) -exec \ -sed -i '/^#include .*\/\/ for/s/\/\/ for/\/\/ Para/' {} + - -echo "✅ Script completado." diff --git a/tools/linter/run_iwyu_dry_run.sh b/tools/linter/run_iwyu_dry_run.sh deleted file mode 100755 index c0d4d69..0000000 --- a/tools/linter/run_iwyu_dry_run.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -# 🏁 Ruta base del proyecto -BASE_DIR="/home/sergio/gitea/coffee_crisis_arcade_edition" - -# 📁 Ruta al build -BUILD_DIR="$BASE_DIR/build" - -# 📄 Archivo de mapping personalizado -MAPPING_FILE="$BASE_DIR/linux_utils/sdl3_mapping.imp" - -# 📦 Generar compile_commands.json -echo "🔧 Generando compile_commands.json..." -cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -S "$BASE_DIR" -B "$BUILD_DIR" - -# 🛠️ Ejecutar IWYU con fix_includes.py -echo "🚀 Ejecutando IWYU..." -iwyu_tool.py -p "$BUILD_DIR" -- -Xiwyu --mapping_file="$MAPPING_FILE" -Xiwyu --verbose=3 \ -| python3 /usr/bin/fix_includes.py --update_comments --reorder --nosafe_headers --dry_run - -# 🧹 Reemplazar // for por // Para en líneas de #include -echo "✍️ Corrigiendo comentarios en includes..." -find "$BASE_DIR" -type f \( -name "*.cpp" -o -name "*.h" \) -exec \ -sed -i '/^#include .*\/\/ for/s/\/\/ for/\/\/ Para/' {} + - -echo "✅ Script completado." diff --git a/tools/linter/run_valgrind.sh b/tools/linter/run_valgrind.sh deleted file mode 100755 index 8b427bf..0000000 --- a/tools/linter/run_valgrind.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -valgrind --suppressions=valgrind_exceptions \ ---leak-check=full \ -~/gitea/coffee_crisis_arcade_edition/coffee_crisis_arcade_edition \ -> ~/gitea/coffee_crisis_arcade_edition/linux_utils/valgrind_out.txt 2>&1 diff --git a/tools/linter/sdl3_mapping.imp b/tools/linter/sdl3_mapping.imp deleted file mode 100644 index 3e9b996..0000000 --- a/tools/linter/sdl3_mapping.imp +++ /dev/null @@ -1,57 +0,0 @@ -[ - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] } -] diff --git a/tools/linter/valgrind_exceptions b/tools/linter/valgrind_exceptions deleted file mode 100644 index 88482a1..0000000 --- a/tools/linter/valgrind_exceptions +++ /dev/null @@ -1,12 +0,0 @@ -{ - ignore_unversioned_libs - Memcheck:Leak - ... - obj:*/lib*/lib*.so -} -{ - ignore_versioned_libs - Memcheck:Leak - ... - obj:*/lib*/lib*.so.* -}