|
|
|
|
@ -8,6 +8,8 @@
|
|
|
|
|
#include "common/small_string.h"
|
|
|
|
|
#include "common/string_util.h"
|
|
|
|
|
|
|
|
|
|
#include <fmt/format.h>
|
|
|
|
|
|
|
|
|
|
#include <cstdarg>
|
|
|
|
|
#include <sstream>
|
|
|
|
|
|
|
|
|
|
@ -17,6 +19,16 @@ namespace CueParser {
|
|
|
|
|
static bool TokenMatch(std::string_view s1, const char* token);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename... T>
|
|
|
|
|
static void SetError(u32 line_number, Error* error, fmt::format_string<T...> fmt, T&&... args)
|
|
|
|
|
{
|
|
|
|
|
SmallString str;
|
|
|
|
|
str.vformat(fmt, fmt::make_format_args(args...));
|
|
|
|
|
|
|
|
|
|
ERROR_LOG("Cue parse error at line {}: {}", line_number, str);
|
|
|
|
|
Error::SetStringFmt(error, "Cue parse error at line {}: {}", line_number, str);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CueParser::TokenMatch(std::string_view s1, const char* token)
|
|
|
|
|
{
|
|
|
|
|
const size_t token_len = std::strlen(token);
|
|
|
|
|
@ -93,18 +105,6 @@ bool CueParser::File::Parse(const std::string& buffer, Error* error)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CueParser::File::SetError(u32 line_number, Error* error, const char* format, ...)
|
|
|
|
|
{
|
|
|
|
|
std::va_list ap;
|
|
|
|
|
SmallString str;
|
|
|
|
|
va_start(ap, format);
|
|
|
|
|
str.vsprintf(format, ap);
|
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
|
|
ERROR_LOG("Cue parse error at line {}: {}", line_number, str.c_str());
|
|
|
|
|
Error::SetStringFmt(error, "Cue parse error at line {}: {}", line_number, str);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string_view CueParser::File::GetToken(const char*& line)
|
|
|
|
|
{
|
|
|
|
|
std::string_view ret;
|
|
|
|
|
@ -231,7 +231,7 @@ bool CueParser::File::ParseLine(const char* line, u32 line_number, Error* error)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetError(line_number, error, "Invalid command '%*s'", static_cast<int>(command.size()), command.data());
|
|
|
|
|
SetError(line_number, error, "Invalid command '{}'", command);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -257,7 +257,8 @@ bool CueParser::File::HandleFileCommand(const char* line, u32 line_number, Error
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SetError(line_number, error, "Only BINARY and WAVE modes are supported");
|
|
|
|
|
SetError(line_number, error, "Unsupported format '{}' for '{}'. Only BINARY and WAVE modes are supported", mode,
|
|
|
|
|
filename);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -287,7 +288,7 @@ bool CueParser::File::HandleTrackCommand(const char* line, u32 line_number, Erro
|
|
|
|
|
const std::optional<s32> track_number = StringUtil::FromChars<s32>(track_number_str);
|
|
|
|
|
if (track_number.value_or(0) < MIN_TRACK_NUMBER || track_number.value_or(0) > MAX_TRACK_NUMBER)
|
|
|
|
|
{
|
|
|
|
|
SetError(line_number, error, "Invalid track number %d", track_number.value_or(0));
|
|
|
|
|
SetError(line_number, error, "Invalid track number {}", track_number.value_or(0));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -311,7 +312,7 @@ bool CueParser::File::HandleTrackCommand(const char* line, u32 line_number, Erro
|
|
|
|
|
mode = TrackMode::Mode2Raw;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SetError(line_number, error, "Invalid mode: '%*s'", static_cast<int>(mode_str.length()), mode_str.data());
|
|
|
|
|
SetError(line_number, error, "Invalid mode: '{}'", mode_str);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -341,13 +342,13 @@ bool CueParser::File::HandleIndexCommand(const char* line, u32 line_number, Erro
|
|
|
|
|
const std::optional<s32> index_number = StringUtil::FromChars<s32>(index_number_str);
|
|
|
|
|
if (index_number.value_or(-1) < MIN_INDEX_NUMBER || index_number.value_or(-1) > MAX_INDEX_NUMBER)
|
|
|
|
|
{
|
|
|
|
|
SetError(line_number, error, "Invalid index number %d", index_number.value_or(-1));
|
|
|
|
|
SetError(line_number, error, "Invalid index number {}", index_number.value_or(-1));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_current_track->GetIndex(static_cast<u32>(index_number.value())) != nullptr)
|
|
|
|
|
{
|
|
|
|
|
SetError(line_number, error, "Duplicate index %d", index_number.value());
|
|
|
|
|
SetError(line_number, error, "Duplicate index {}", index_number.value());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -361,7 +362,7 @@ bool CueParser::File::HandleIndexCommand(const char* line, u32 line_number, Erro
|
|
|
|
|
const std::optional<MSF> msf(GetMSF(msf_str));
|
|
|
|
|
if (!msf.has_value())
|
|
|
|
|
{
|
|
|
|
|
SetError(line_number, error, "Invalid index location '%*s'", static_cast<int>(msf_str.size()), msf_str.data());
|
|
|
|
|
SetError(line_number, error, "Invalid index location '{}'", msf_str);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -379,7 +380,7 @@ bool CueParser::File::HandlePregapCommand(const char* line, u32 line_number, Err
|
|
|
|
|
|
|
|
|
|
if (m_current_track->zero_pregap.has_value())
|
|
|
|
|
{
|
|
|
|
|
SetError(line_number, error, "Pregap already specified for track %u", m_current_track->number);
|
|
|
|
|
SetError(line_number, error, "Pregap already specified for track {}", m_current_track->number);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -393,7 +394,7 @@ bool CueParser::File::HandlePregapCommand(const char* line, u32 line_number, Err
|
|
|
|
|
const std::optional<MSF> msf(GetMSF(msf_str));
|
|
|
|
|
if (!msf.has_value())
|
|
|
|
|
{
|
|
|
|
|
SetError(line_number, error, "Invalid pregap location '%*s'", static_cast<int>(msf_str.size()), msf_str.data());
|
|
|
|
|
SetError(line_number, error, "Invalid pregap location '{}'", msf_str);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -438,7 +439,7 @@ bool CueParser::File::CompleteLastTrack(u32 line_number, Error* error)
|
|
|
|
|
const MSF* index1 = m_current_track->GetIndex(1);
|
|
|
|
|
if (!index1)
|
|
|
|
|
{
|
|
|
|
|
SetError(line_number, error, "Track %u is missing index 1", m_current_track->number);
|
|
|
|
|
SetError(line_number, error, "Track {} is missing index 1", m_current_track->number);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -451,7 +452,7 @@ bool CueParser::File::CompleteLastTrack(u32 line_number, Error* error)
|
|
|
|
|
const MSF* prev_index = m_current_track->GetIndex(index_number - 1);
|
|
|
|
|
if (prev_index && *prev_index > index_msf)
|
|
|
|
|
{
|
|
|
|
|
SetError(line_number, error, "Index %u is after index %u in track %u", index_number - 1, index_number,
|
|
|
|
|
SetError(line_number, error, "Index {} is after index {} in track {}", index_number - 1, index_number,
|
|
|
|
|
m_current_track->number);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
@ -483,7 +484,7 @@ bool CueParser::File::SetTrackLengths(u32 line_number, Error* error)
|
|
|
|
|
{
|
|
|
|
|
if (previous_track->start > track.start)
|
|
|
|
|
{
|
|
|
|
|
SetError(line_number, error, "Track %u start greater than track %u start", previous_track->number,
|
|
|
|
|
SetError(line_number, error, "Track {} start greater than track {} start", previous_track->number,
|
|
|
|
|
track.number);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|