Files
jaildoctors_dilemma/tools/linter/run_cppcheck.sh
2025-11-07 17:01:29 +01:00

197 lines
6.8 KiB
Bash
Executable File

#!/bin/bash
# ============================================================================
# CONFIGURACIÓN - Editar estas constantes para personalizar el script
# ============================================================================
# Detectar la ubicación del script y la raíz del proyecto
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
# Rutas del proyecto
DEFAULT_ANALYSIS_PATH="$PROJECT_ROOT/source"
INCLUDE_PATH="$PROJECT_ROOT/source"
SUPPRESSIONS_FILE="$SCRIPT_DIR/cppcheck_suppressions"
OUTPUT_DIR="$SCRIPT_DIR"
BUILD_DIR="$PROJECT_ROOT/build"
COMPILE_COMMANDS="$BUILD_DIR/compile_commands.json"
# Parámetros de compilación comunes (fallback para análisis de archivos específicos)
CPPCHECK_STD="--std=c++20"
# Calcular número de threads (cores - 1, mínimo 1)
THREADS=$(($(nproc) - 1))
[[ $THREADS -lt 1 ]] && THREADS=1
# ============================================================================
# Función para asegurar que compile_commands.json existe
ensure_compile_commands() {
if [[ ! -f "$COMPILE_COMMANDS" ]]; then
echo "⚠ compile_commands.json no encontrado en $BUILD_DIR"
echo "Generando compile_commands.json con CMake..."
# Crear directorio build si no existe
mkdir -p "$BUILD_DIR"
# Ejecutar CMake para generar compile_commands.json
(cd "$BUILD_DIR" && cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. > /dev/null 2>&1)
if [[ ! -f "$COMPILE_COMMANDS" ]]; then
echo "❌ Error: No se pudo generar compile_commands.json"
echo "Por favor, ejecuta manualmente:"
echo " cd $BUILD_DIR && cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .."
exit 1
fi
echo "✓ compile_commands.json generado exitosamente"
else
echo "✓ Usando compile_commands.json existente: $COMPILE_COMMANDS"
fi
}
# Función para mostrar el uso del script
mostrar_uso() {
echo "Uso: $0 [OPCIÓN] [RUTA]"
echo ""
echo "Opciones de análisis:"
echo " -w, --warning Ejecutar cppcheck con warning, style, performance"
echo " -a, --all Ejecutar cppcheck con todas las opciones habilitadas"
echo " -u, --unused Ejecutar cppcheck para unusedFunction"
echo ""
echo "Opciones de ruta:"
echo " -p, --path <ruta> Especificar ruta a analizar (default: PROJECT_ROOT/source)"
echo " [RUTA] Ruta como último argumento posicional"
echo ""
echo "Ejemplos:"
echo " $0 --warning"
echo " $0 -w --path ../src/"
echo " $0 --all /path/to/code/"
echo " $0 -u ../source/"
}
# Inicializar las variables
opcion=""
ruta="$DEFAULT_ANALYSIS_PATH"
# Procesar las opciones
while [[ $# -gt 0 ]]; do
case $1 in
-w|--warning)
opcion="warning"
shift
;;
-a|--all)
opcion="all"
shift
;;
-u|--unused)
opcion="unused"
shift
;;
-p|--path)
if [[ -n "$2" && "$2" != -* ]]; then
ruta="$2"
shift 2
else
echo "Error: --path requiere un argumento"
mostrar_uso
exit 1
fi
;;
-h|--help)
mostrar_uso
exit 0
;;
-*)
echo "Error: Opción desconocida: $1"
mostrar_uso
exit 1
;;
*)
# Argumento posicional (asumimos que es la ruta)
ruta="$1"
shift
;;
esac
done
# Verificar que se haya especificado una opción de análisis
if [[ -z "$opcion" ]]; then
echo "Error: Debe especificar una opción de análisis (-w, -a, o -u)"
mostrar_uso
exit 1
fi
# Ejecutar según la opción seleccionada
case $opcion in
warning)
ensure_compile_commands
if [[ "$ruta" == "$DEFAULT_ANALYSIS_PATH" ]]; then
echo "Ejecutando cppcheck con warning, style, performance en proyecto completo (usando $THREADS threads)"
cppcheck --force --enable=warning,style,performance \
--check-level=exhaustive \
-j$THREADS \
--project="$COMPILE_COMMANDS" \
--suppressions-list="$SUPPRESSIONS_FILE" \
2>"$OUTPUT_DIR/cppcheck-result-warning-style-performance.txt"
else
echo "Ejecutando cppcheck con warning, style, performance en: $ruta (usando $THREADS threads)"
cppcheck --force --enable=warning,style,performance $CPPCHECK_STD \
--check-level=exhaustive \
-j$THREADS \
-I "$INCLUDE_PATH" \
--suppressions-list="$SUPPRESSIONS_FILE" \
"$ruta" \
2>"$OUTPUT_DIR/cppcheck-result-warning-style-performance.txt"
fi
echo "Resultados guardados en: $OUTPUT_DIR/cppcheck-result-warning-style-performance.txt"
;;
all)
ensure_compile_commands
if [[ "$ruta" == "$DEFAULT_ANALYSIS_PATH" ]]; then
echo "Ejecutando cppcheck con todas las opciones en proyecto completo (usando $THREADS threads)"
cppcheck --force --enable=all \
-j$THREADS \
--project="$COMPILE_COMMANDS" \
--suppress=missingIncludeSystem \
--suppressions-list="$SUPPRESSIONS_FILE" \
2>"$OUTPUT_DIR/cppcheck-result-all.txt"
else
echo "Ejecutando cppcheck con todas las opciones en: $ruta (usando $THREADS threads)"
cppcheck --force --enable=all -I /usr/include -I "$INCLUDE_PATH" $CPPCHECK_STD \
-j$THREADS \
--suppress=missingIncludeSystem \
--suppressions-list="$SUPPRESSIONS_FILE" \
"$ruta" \
2>"$OUTPUT_DIR/cppcheck-result-all.txt"
fi
echo "Resultados guardados en: $OUTPUT_DIR/cppcheck-result-all.txt"
;;
unused)
ensure_compile_commands
if [[ "$ruta" == "$DEFAULT_ANALYSIS_PATH" ]]; then
echo "Ejecutando cppcheck para unusedFunction en proyecto completo (usando $THREADS threads)"
cppcheck --enable=style \
-j$THREADS \
--project="$COMPILE_COMMANDS" \
--suppressions-list="$SUPPRESSIONS_FILE" \
2>"$OUTPUT_DIR/cppcheck-result-unusedFunction.txt"
else
echo "Ejecutando cppcheck para unusedFunction en: $ruta (usando $THREADS threads)"
cppcheck --enable=style $CPPCHECK_STD \
-j$THREADS \
-I "$INCLUDE_PATH" \
--suppressions-list="$SUPPRESSIONS_FILE" \
"$ruta" \
2>"$OUTPUT_DIR/cppcheck-result-unusedFunction.txt"
fi
echo "Resultados guardados en: $OUTPUT_DIR/cppcheck-result-unusedFunction.txt"
;;
*)
echo "Error: Opción inválida"
mostrar_uso
exit 1
;;
esac