LCOV - code coverage report
Current view: top level - src - VehicleUtils.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 59 59
Test Date: 2026-03-03 13:56:25 Functions: 100.0 % 3 3
Branches: 97.7 % 132 129

             Branch data     Line data    Source code
       1                 :             : #include "VehicleUtils.h"
       2                 :             : #include <algorithm>
       3                 :             : #include <string>
       4                 :             : 
       5                 :             : // Helper: Parse car class from strings (v0.7.44 Refactor)
       6                 :             : // Returns a ParsedVehicleClass enum for internal logic and categorization
       7                 :        1386 : ParsedVehicleClass ParseVehicleClass(const char* className, const char* vehicleName) {
       8   [ +  +  +  - ]:        2772 :     std::string cls = className ? className : "";
       9   [ +  +  +  - ]:        1386 :     std::string name = vehicleName ? vehicleName : "";
      10                 :             : 
      11                 :             :     // Normalize for case-insensitive matching
      12                 :        1386 :     std::transform(cls.begin(), cls.end(), cls.begin(), ::toupper);
      13                 :        1386 :     std::transform(name.begin(), name.end(), name.begin(), ::toupper);
      14                 :             : 
      15                 :             :     // 1. Primary Identification via Class Name (Hierarchical)
      16   [ +  +  +  +  :        1386 :     if (cls.find("HYPERCAR") != std::string::npos || cls.find("LMH") != std::string::npos || cls.find("LMDH") != std::string::npos) {
             +  +  +  + ]
      17                 :          18 :         return ParsedVehicleClass::HYPERCAR;
      18                 :             :     }
      19                 :             :     
      20         [ +  + ]:        1368 :     if (cls.find("LMP2") != std::string::npos) {
      21   [ +  +  +  +  :          22 :         if (cls.find("ELMS") != std::string::npos || name.find("DERESTRICTED") != std::string::npos) { return ParsedVehicleClass::LMP2_UNRESTRICTED; }
                   +  + ]
      22                 :             :         // Issue #225: "LMP2" in LMU refers to the restricted WEC spec.
      23                 :          16 :         return ParsedVehicleClass::LMP2_RESTRICTED;
      24                 :             :     }
      25                 :             : 
      26         [ +  + ]:        1346 :     if (cls.find("LMP3") != std::string::npos) return ParsedVehicleClass::LMP3;
      27         [ +  + ]:        1345 :     if (cls.find("GTE") != std::string::npos) return ParsedVehicleClass::GTE;
      28                 :             :     // NOTE: LMGT3 check is redundant here as GT3 would match it first.
      29   [ +  +  -  +  :        1336 :     if (cls.find("GT3") != std::string::npos || cls.find("LMGT3") != std::string::npos) return ParsedVehicleClass::GT3;
                   +  + ]
      30                 :             : 
      31                 :             :     // 2. Secondary Identification via Vehicle Name Keywords (Fallback)
      32         [ +  + ]:          51 :     if (!name.empty()) {
      33                 :             :         // Hypercars
      34   [ +  +  +  + ]:         136 :         if (name.find("499P") != std::string::npos || name.find("GR010") != std::string::npos ||
      35   [ +  +  +  + ]:         129 :             name.find("963") != std::string::npos || name.find("9X8") != std::string::npos ||
      36   [ +  +  +  + ]:         123 :             name.find("V-SERIES.R") != std::string::npos || name.find("SCG 007") != std::string::npos ||
      37   [ +  +  +  + ]:         117 :             name.find("GLICKENHAUS") != std::string::npos || name.find("VANWALL") != std::string::npos ||
      38   [ +  +  +  + ]:         111 :             name.find("A424") != std::string::npos || name.find("SC63") != std::string::npos ||
      39   [ +  +  +  + ]:         105 :             name.find("VALKYRIE") != std::string::npos || name.find("M HYBRID") != std::string::npos ||
      40   [ +  +  +  +  :         126 :             name.find("TIPO 6") != std::string::npos || name.find("680") != std::string::npos) {
                   +  + ]
      41                 :          15 :             return ParsedVehicleClass::HYPERCAR;
      42                 :             :         }
      43                 :             :         
      44                 :             :         // LMP2
      45   [ +  +  +  +  :          32 :         if (name.find("ORECA") != std::string::npos || name.find("07") != std::string::npos) {
                   +  + ]
      46                 :           3 :             return ParsedVehicleClass::LMP2_UNSPECIFIED;
      47                 :             :         }
      48                 :             : 
      49                 :             :         // LMP3
      50   [ +  +  +  + ]:          82 :         if (name.find("LIGIER") != std::string::npos || name.find("GINETTA") != std::string::npos ||
      51   [ +  +  +  + ]:          75 :             name.find("DUQUEINE") != std::string::npos || name.find("P320") != std::string::npos ||
      52   [ +  +  +  +  :         102 :             name.find("P325") != std::string::npos || name.find("G61") != std::string::npos ||
             +  +  +  + ]
      53                 :          22 :             name.find("D09") != std::string::npos) {
      54                 :           8 :             return ParsedVehicleClass::LMP3;
      55                 :             :         }
      56                 :             : 
      57                 :             :         // GTE
      58   [ +  +  +  + ]:          60 :         if (name.find("RSR-19") != std::string::npos || name.find("488 GTE") != std::string::npos ||
      59   [ +  +  +  +  :          60 :             name.find("C8.R") != std::string::npos || name.find("VANTAGE AMR") != std::string::npos) {
                   +  + ]
      60                 :           4 :             return ParsedVehicleClass::GTE;
      61                 :             :         }
      62                 :             : 
      63                 :             :         // GT3
      64   [ +  +  +  + ]:          48 :         if (name.find("LMGT3") != std::string::npos || name.find("296 GT3") != std::string::npos ||
      65   [ +  +  +  + ]:          42 :             name.find("M4 GT3") != std::string::npos || name.find("Z06 GT3") != std::string::npos ||
      66   [ +  +  +  + ]:          36 :             name.find("HURACAN") != std::string::npos || name.find("RC F") != std::string::npos ||
      67   [ +  +  +  +  :          44 :             name.find("720S") != std::string::npos || name.find("MUSTANG") != std::string::npos) {
                   +  + ]
      68                 :           8 :             return ParsedVehicleClass::GT3;
      69                 :             :         }
      70                 :             :     }
      71                 :             : 
      72                 :          13 :     return ParsedVehicleClass::UNKNOWN;
      73                 :        1386 : }
      74                 :             : 
      75                 :             : // Lookup table: Map ParsedVehicleClass to Seed Load (Newtons)
      76                 :        1339 : double GetDefaultLoadForClass(ParsedVehicleClass vclass) {
      77   [ +  +  +  +  :        1339 :     switch (vclass) {
             +  +  +  + ]
      78                 :          16 :         case ParsedVehicleClass::HYPERCAR:         return 9500.0;
      79                 :           4 :         case ParsedVehicleClass::LMP2_UNRESTRICTED: return 8500.0;
      80                 :          13 :         case ParsedVehicleClass::LMP2_RESTRICTED:   return 7500.0;
      81                 :           1 :         case ParsedVehicleClass::LMP2_UNSPECIFIED:  return 8000.0;
      82                 :           2 :         case ParsedVehicleClass::LMP3:             return 5800.0;
      83                 :           9 :         case ParsedVehicleClass::GTE:              return 5500.0;
      84                 :        1281 :         case ParsedVehicleClass::GT3:              return 4800.0;
      85                 :          13 :         default:                                   return 4500.0;
      86                 :             :     }
      87                 :             : }
      88                 :             : 
      89                 :             : // Helper: String representation of parsed class for logging and UI
      90                 :         673 : const char* VehicleClassToString(ParsedVehicleClass vclass) {
      91   [ +  +  +  +  :         673 :     switch (vclass) {
             +  +  +  + ]
      92                 :           9 :         case ParsedVehicleClass::HYPERCAR:         return "Hypercar";
      93                 :           3 :         case ParsedVehicleClass::LMP2_UNRESTRICTED: return "LMP2 Unrestricted";
      94                 :           7 :         case ParsedVehicleClass::LMP2_RESTRICTED:   return "LMP2 Restricted";
      95                 :           1 :         case ParsedVehicleClass::LMP2_UNSPECIFIED:  return "LMP2 Unspecified";
      96                 :           2 :         case ParsedVehicleClass::LMP3:             return "LMP3";
      97                 :           6 :         case ParsedVehicleClass::GTE:              return "GTE";
      98                 :         640 :         case ParsedVehicleClass::GT3:              return "GT3";
      99                 :           5 :         default:                                   return "Unknown";
     100                 :             :     }
     101                 :             : }
        

Generated by: LCOV version 2.0-1