LCOV - code coverage report
Current view: top level - jdx/util - MultilineTuplesParser.cpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 52 57 91.2 %
Date: 2025-06-15 16:18:27 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /* Copyright (C) 2025 Robert Schiwon
       2             :  *
       3             :  * This file is part of libjdx.
       4             :  *
       5             :  * libjdx is free software: you can redistribute it and/or modify it under the
       6             :  * terms of the GNU Lesser General Public License as published by the Free
       7             :  * Software Foundation, either version 3 of the License, or (at your option) any
       8             :  * later version.
       9             :  *
      10             :  * libjdx is distributed in the hope that it will be useful, but WITHOUT ANY
      11             :  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      12             :  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
      13             :  * details.
      14             :  *
      15             :  * You should have received a copy of the GNU Lesser General Public License
      16             :  * along with libjdx. If not, see <https://www.gnu.org/licenses/>.
      17             :  */
      18             : #include "util/MultilineTuplesParser.hpp"
      19             : #include "jdx/ParseException.hpp"
      20             : #include "util/LdrUtils.hpp"
      21             : #include "util/StringUtils.hpp"
      22             : 
      23          27 : libjdx::jdx::util::MultilineTuplesParser::MultilineTuplesParser(
      24             :     io::TextReader& reader, std::string variableList, std::string ldrName,
      25          27 :     std::string lineBreakChars)
      26          27 :     : TuplesParser(std::move(variableList), std::move(ldrName))
      27             :     , m_reader{reader}
      28          54 :     , m_lineBreakChars{std::move(lineBreakChars)}
      29             : {
      30          27 : }
      31             : 
      32          66 : std::optional<std::string> libjdx::jdx::util::MultilineTuplesParser::nextTuple()
      33             : {
      34          66 :     const auto& ldrName = getLdrName();
      35         132 :     std::string tupleString{};
      36             :     // find start
      37          71 :     while (!m_reader.eof())
      38             :     {
      39          70 :         std::streampos pos = m_reader.tellg();
      40          71 :         auto line = m_reader.readLine();
      41          71 :         auto lineStart = util::stripLineComment(line, true).first;
      42          70 :         if (isTupleStart(lineStart))
      43             :         {
      44          50 :             tupleString.append(lineStart);
      45          50 :             break;
      46             :         }
      47          20 :         if (util::isLdrStart(lineStart))
      48             :         {
      49             :             // LDR ended, no tuple
      50          14 :             m_reader.seekg(pos);
      51          14 :             return std::nullopt;
      52             :         }
      53           6 :         if (!lineStart.empty())
      54             :         {
      55           2 :             throw ParseException(std::string{"Illegal string found in "}
      56           1 :                                      .append(ldrName)
      57           1 :                                      .append(": ")
      58           3 :                                      .append(line));
      59             :         }
      60             :     }
      61          51 :     if (isTupleEnd(tupleString))
      62             :     {
      63          30 :         return tupleString;
      64             :     }
      65             :     // read to end of current tuple
      66          49 :     while (!m_reader.eof())
      67             :     {
      68          48 :         std::streampos pos = m_reader.tellg();
      69          51 :         auto line = m_reader.readLine();
      70          51 :         auto lineStart = util::stripLineComment(line, true).first;
      71             : 
      72          48 :         if (util::isLdrStart(lineStart))
      73             :         {
      74             :             // LDR ended before end of last tuple
      75           3 :             m_reader.seekg(pos);
      76             :             throw ParseException(
      77           6 :                 std::string{"No closing parenthesis found for "}
      78           3 :                     .append(ldrName)
      79           3 :                     .append(" entry: ")
      80           9 :                     .append(tupleString));
      81             :         }
      82          45 :         tupleString.append(m_lineBreakChars);
      83          45 :         tupleString.append(lineStart);
      84          45 :         if (isTupleEnd(lineStart))
      85             :         {
      86          17 :             return tupleString;
      87             :         }
      88          28 :         if (m_reader.eof() || util::isLdrStart(lineStart))
      89             :         {
      90             :             // LDR ended before end of last tuple
      91           0 :             m_reader.seekg(pos);
      92             :             throw ParseException(
      93           0 :                 std::string{"No closing parenthesis found for "}
      94           0 :                     .append(ldrName)
      95           0 :                     .append(" entry: ")
      96           0 :                     .append(tupleString));
      97             :         }
      98             :     }
      99             :     throw ParseException(
     100           2 :         std::string{"File ended before closing parenthesis was found for "}
     101           1 :             .append(ldrName)
     102           1 :             .append(": ")
     103           3 :             .append(tupleString));
     104             : }
     105             : 
     106          70 : bool libjdx::jdx::util::MultilineTuplesParser::isTupleStart(
     107             :     const std::string& stringValue)
     108             : {
     109          70 :     std::string value{stringValue};
     110          70 :     util::trimLeft(value);
     111         140 :     return !value.empty() && value.at(0) == '(';
     112             : }
     113             : 
     114          96 : bool libjdx::jdx::util::MultilineTuplesParser::isTupleEnd(
     115             :     const std::string& stringValue)
     116             : {
     117          96 :     std::string value{stringValue};
     118          96 :     util::trimRight(value);
     119         192 :     return !value.empty() && value.back() == ')';
     120             : }

Generated by: LCOV version 1.14