LCOV - code coverage report
Current view: top level - src - VehicleUtils.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 61 61
Test Date: 2026-03-01 21:30:38 Functions: 100.0 % 3 3
Branches: 97.8 % 134 131

             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                 :         162 : ParsedVehicleClass ParseVehicleClass(const char* className, const char* vehicleName) {
       8   [ +  +  +  - ]:         324 :     std::string cls = className ? className : "";
       9   [ +  +  +  - ]:         162 :     std::string name = vehicleName ? vehicleName : "";
      10                 :             : 
      11                 :             :     // Normalize for case-insensitive matching
      12                 :         162 :     std::transform(cls.begin(), cls.end(), cls.begin(), ::toupper);
      13                 :         162 :     std::transform(name.begin(), name.end(), name.begin(), ::toupper);
      14                 :             : 
      15                 :             :     // 1. Primary Identification via Class Name (Hierarchical)
      16   [ +  +  +  +  :         162 :     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         [ +  + ]:         144 :     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                 :          16 :         volatile bool is_wec = (cls.find("WEC") != std::string::npos);
      23         [ +  + ]:          16 :         if (is_wec) { return ParsedVehicleClass::LMP2_RESTRICTED; }
      24                 :          12 :         return ParsedVehicleClass::LMP2_UNSPECIFIED;
      25                 :             :     }
      26                 :             : 
      27         [ +  + ]:         122 :     if (cls.find("LMP3") != std::string::npos) return ParsedVehicleClass::LMP3;
      28         [ +  + ]:         121 :     if (cls.find("GTE") != std::string::npos) return ParsedVehicleClass::GTE;
      29                 :             :     // NOTE: LMGT3 check is redundant here as GT3 would match it first.
      30   [ +  +  -  +  :         114 :     if (cls.find("GT3") != std::string::npos || cls.find("LMGT3") != std::string::npos) return ParsedVehicleClass::GT3;
                   +  + ]
      31                 :             : 
      32                 :             :     // 2. Secondary Identification via Vehicle Name Keywords (Fallback)
      33         [ +  + ]:          49 :     if (!name.empty()) {
      34                 :             :         // Hypercars
      35   [ +  +  +  + ]:         133 :         if (name.find("499P") != std::string::npos || name.find("GR010") != std::string::npos ||
      36   [ +  +  +  + ]:         126 :             name.find("963") != std::string::npos || name.find("9X8") != std::string::npos ||
      37   [ +  +  +  + ]:         120 :             name.find("V-SERIES.R") != std::string::npos || name.find("SCG 007") != std::string::npos ||
      38   [ +  +  +  + ]:         114 :             name.find("GLICKENHAUS") != std::string::npos || name.find("VANWALL") != std::string::npos ||
      39   [ +  +  +  + ]:         108 :             name.find("A424") != std::string::npos || name.find("SC63") != std::string::npos ||
      40   [ +  +  +  + ]:         102 :             name.find("VALKYRIE") != std::string::npos || name.find("M HYBRID") != std::string::npos ||
      41   [ +  +  +  +  :         123 :             name.find("TIPO 6") != std::string::npos || name.find("680") != std::string::npos) {
                   +  + ]
      42                 :          15 :             return ParsedVehicleClass::HYPERCAR;
      43                 :             :         }
      44                 :             :         
      45                 :             :         // LMP2
      46   [ +  +  +  +  :          31 :         if (name.find("ORECA") != std::string::npos || name.find("07") != std::string::npos) {
                   +  + ]
      47                 :           3 :             return ParsedVehicleClass::LMP2_UNSPECIFIED;
      48                 :             :         }
      49                 :             : 
      50                 :             :         // LMP3
      51   [ +  +  +  + ]:          79 :         if (name.find("LIGIER") != std::string::npos || name.find("GINETTA") != std::string::npos ||
      52   [ +  +  +  + ]:          72 :             name.find("DUQUEINE") != std::string::npos || name.find("P320") != std::string::npos ||
      53   [ +  +  +  +  :          98 :             name.find("P325") != std::string::npos || name.find("G61") != std::string::npos ||
             +  +  +  + ]
      54                 :          21 :             name.find("D09") != std::string::npos) {
      55                 :           8 :             return ParsedVehicleClass::LMP3;
      56                 :             :         }
      57                 :             : 
      58                 :             :         // GTE
      59   [ +  +  +  + ]:          57 :         if (name.find("RSR-19") != std::string::npos || name.find("488 GTE") != std::string::npos ||
      60   [ +  +  +  +  :          57 :             name.find("C8.R") != std::string::npos || name.find("VANTAGE AMR") != std::string::npos) {
                   +  + ]
      61                 :           4 :             return ParsedVehicleClass::GTE;
      62                 :             :         }
      63                 :             : 
      64                 :             :         // GT3
      65   [ +  +  +  + ]:          45 :         if (name.find("LMGT3") != std::string::npos || name.find("296 GT3") != std::string::npos ||
      66   [ +  +  +  + ]:          39 :             name.find("M4 GT3") != std::string::npos || name.find("Z06 GT3") != std::string::npos ||
      67   [ +  +  +  + ]:          33 :             name.find("HURACAN") != std::string::npos || name.find("RC F") != std::string::npos ||
      68   [ +  +  +  +  :          41 :             name.find("720S") != std::string::npos || name.find("MUSTANG") != std::string::npos) {
                   +  + ]
      69                 :           8 :             return ParsedVehicleClass::GT3;
      70                 :             :         }
      71                 :             :     }
      72                 :             : 
      73                 :          11 :     return ParsedVehicleClass::UNKNOWN;
      74                 :         162 : }
      75                 :             : 
      76                 :             : // Lookup table: Map ParsedVehicleClass to Seed Load (Newtons)
      77                 :         115 : double GetDefaultLoadForClass(ParsedVehicleClass vclass) {
      78   [ +  +  +  +  :         115 :     switch (vclass) {
             +  +  +  + ]
      79                 :          16 :         case ParsedVehicleClass::HYPERCAR:         return 9500.0;
      80                 :           4 :         case ParsedVehicleClass::LMP2_UNRESTRICTED: return 8500.0;
      81                 :           3 :         case ParsedVehicleClass::LMP2_RESTRICTED:   return 7500.0;
      82                 :          11 :         case ParsedVehicleClass::LMP2_UNSPECIFIED:  return 8000.0;
      83                 :           2 :         case ParsedVehicleClass::LMP3:             return 5800.0;
      84                 :           7 :         case ParsedVehicleClass::GTE:              return 5500.0;
      85                 :          61 :         case ParsedVehicleClass::GT3:              return 4800.0;
      86                 :          11 :         default:                                   return 4500.0;
      87                 :             :     }
      88                 :             : }
      89                 :             : 
      90                 :             : // Helper: String representation of parsed class for logging and UI
      91                 :          61 : const char* VehicleClassToString(ParsedVehicleClass vclass) {
      92   [ +  +  +  +  :          61 :     switch (vclass) {
             +  +  +  + ]
      93                 :           9 :         case ParsedVehicleClass::HYPERCAR:         return "Hypercar";
      94                 :           3 :         case ParsedVehicleClass::LMP2_UNRESTRICTED: return "LMP2 Unrestricted";
      95                 :           2 :         case ParsedVehicleClass::LMP2_RESTRICTED:   return "LMP2 Restricted";
      96                 :           6 :         case ParsedVehicleClass::LMP2_UNSPECIFIED:  return "LMP2 Unspecified";
      97                 :           2 :         case ParsedVehicleClass::LMP3:             return "LMP3";
      98                 :           5 :         case ParsedVehicleClass::GTE:              return "GTE";
      99                 :          30 :         case ParsedVehicleClass::GT3:              return "GT3";
     100                 :           4 :         default:                                   return "Unknown";
     101                 :             :     }
     102                 :             : }
        

Generated by: LCOV version 2.0-1