Start detecting which files have errors.

Guess we needed this as a class/struct after all.
This commit is contained in:
Jason Felds
2011-06-14 13:35:59 -04:00
parent 23e71e1574
commit 3b1260bb79
4 changed files with 186 additions and 53 deletions
+66 -19
View File
@@ -13,6 +13,16 @@
#include "Attack.h"
#include "PrefsManager.h"
void SMLoader::SetSongTitle(const RString & title)
{
this->songTitle = title;
}
RString SMLoader::GetSongTitle() const
{
return this->songTitle;
}
bool SMLoader::LoadFromDir( const RString &sPath, Song &out )
{
vector<RString> aFileNames;
@@ -210,10 +220,11 @@ bool SMLoader::ProcessBPMs( TimingData &out, const RString line, const int rowsP
{
vector<RString> arrayBPMChangeValues;
split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues );
// XXX: Hard to tell which file caused this.
if( arrayBPMChangeValues.size() != 2 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #BPMs value \"%s\" (must have exactly one '='), ignored.",
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid #BPMs value \"%s\" (must have exactly one '='), ignored.",
arrayBPMChangeExpressions[b].c_str() );
continue;
}
@@ -281,8 +292,9 @@ void SMLoader::ProcessStops( TimingData &out, const RString line, const int rows
split( arrayFreezeExpressions[f], "=", arrayFreezeValues );
if( arrayFreezeValues.size() != 2 )
{
// XXX: Hard to tell which file caused this.
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #STOPS value \"%s\" (must have exactly one '='), ignored.",
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid #STOPS value \"%s\" (must have exactly one '='), ignored.",
arrayFreezeExpressions[f].c_str() );
continue;
}
@@ -343,8 +355,9 @@ void SMLoader::ProcessDelays( TimingData &out, const RString line, const int row
split( arrayDelayExpressions[f], "=", arrayDelayValues );
if( arrayDelayValues.size() != 2 )
{
// XXX: Hard to tell which file caused this.
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #DELAYS value \"%s\" (must have exactly one '='), ignored.",
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid #DELAYS value \"%s\" (must have exactly one '='), ignored.",
arrayDelayExpressions[f].c_str() );
continue;
}
@@ -362,7 +375,11 @@ void SMLoader::ProcessDelays( TimingData &out, const RString line, const int row
if(fFreezeSeconds > 0.0f)
out.AddStopSegment( new_seg );
else
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid delay at beat %f, length %f.", fFreezeBeat, fFreezeSeconds );
LOG->UserLog(
"Song file",
this->GetSongTitle(),
"has an invalid delay at beat %f, length %f.",
fFreezeBeat, fFreezeSeconds );
}
}
@@ -378,7 +395,10 @@ void SMLoader::ProcessTimeSignatures( TimingData &out, const RString line, const
if( vs2.size() < 3 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with %i values.", (int)vs2.size() );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid time signature change with %i values.",
static_cast<int>(vs2.size()) );
continue;
}
@@ -388,19 +408,28 @@ void SMLoader::ProcessTimeSignatures( TimingData &out, const RString line, const
if( fBeat < 0 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f.", fBeat );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid time signature change with beat %f.",
fBeat );
continue;
}
if( seg.GetNum() < 1 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.GetNum() );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid time signature change with beat %f, iNumerator %i.",
fBeat, seg.GetNum() );
continue;
}
if( seg.GetDen() < 1 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iDenominator %i.", fBeat, seg.GetDen() );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid time signature change with beat %f, iDenominator %i.",
fBeat, seg.GetDen() );
continue;
}
@@ -419,8 +448,9 @@ void SMLoader::ProcessTickcounts( TimingData &out, const RString line, const int
split( arrayTickcountExpressions[f], "=", arrayTickcountValues );
if( arrayTickcountValues.size() != 2 )
{
// XXX: Hard to tell which file caused this.
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #TICKCOUNTS value \"%s\" (must have exactly one '='), ignored.",
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid #TICKCOUNTS value \"%s\" (must have exactly one '='), ignored.",
arrayTickcountExpressions[f].c_str() );
continue;
}
@@ -455,7 +485,10 @@ void SMLoader::ProcessSpeeds( TimingData &out, const RString line, const int row
if( vs2.size() < 4 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with %i values.", (int)vs2.size() );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an speed change with %i values.",
static_cast<int>(vs2.size()) );
continue;
}
@@ -466,13 +499,19 @@ void SMLoader::ProcessSpeeds( TimingData &out, const RString line, const int row
if( fBeat < 0 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f.", fBeat );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an speed change with beat %f.",
fBeat );
continue;
}
if( seg.GetLength() < 0 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f, length %f.", fBeat, seg.GetLength() );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an speed change with beat %f, length %f.",
fBeat, seg.GetLength() );
continue;
}
@@ -489,10 +528,11 @@ void SMLoader::ProcessFakes( TimingData &out, const RString line, const int rows
{
vector<RString> arrayFakeValues;
split( arrayFakeExpressions[b], "=", arrayFakeValues );
// XXX: Hard to tell which file caused this.
if( arrayFakeValues.size() != 2 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #FAKES value \"%s\" (must have exactly one '='), ignored.",
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid #FAKES value \"%s\" (must have exactly one '='), ignored.",
arrayFakeExpressions[b].c_str() );
continue;
}
@@ -504,7 +544,10 @@ void SMLoader::ProcessFakes( TimingData &out, const RString line, const int rows
out.AddFakeSegment( FakeSegment(fBeat, fNewBeat) );
else
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Fake at beat %f, BPM %f.", fBeat, fNewBeat );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid Fake at beat %f, BPM %f.",
fBeat, fNewBeat );
}
}
}
@@ -619,7 +662,10 @@ bool SMLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache
/* Don't use GetMainAndSubTitlesFromFullTitle; that's only for heuristically
* splitting other formats that *don't* natively support #SUBTITLE. */
if( sValueName=="TITLE" )
{
out.m_sMainTitle = sParams[1];
this->SetSongTitle(sParams[1]);
}
else if( sValueName=="SUBTITLE" )
out.m_sSubTitle = sParams[1];
@@ -892,6 +938,7 @@ bool SMLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath
}
RString sSongFullTitle = sParams[1];
this->SetSongTitle(sParams[1]);
sSongFullTitle.Replace( '\\', '/' );
pSong = SONGMAN->FindSong( sSongFullTitle );
+14 -2
View File
@@ -21,9 +21,9 @@ const int MAX_EDIT_STEPS_SIZE_BYTES = 60*1024; // 60KB
/** @brief Reads a Song from an .SM file. */
struct SMLoader
{
SMLoader() : fileExt(".sm") {}
SMLoader() : fileExt(".sm"), songTitle() {}
SMLoader(RString ext) : fileExt(ext) {}
SMLoader(RString ext) : fileExt(ext), songTitle() {}
virtual ~SMLoader() {}
@@ -162,9 +162,21 @@ protected:
* @return the file extension. */
RString GetFileExtension() const { return fileExt; }
/**
* @brief Set the song title.
* @param t the song title. */
virtual void SetSongTitle(const RString & title);
/**
* @brief Get the song title.
* @return the song title. */
virtual RString GetSongTitle() const;
private:
/** @brief The file extension in use. */
const RString fileExt;
/** @brief The song title that is being processed. */
RString songTitle;
};
#endif
+44 -12
View File
@@ -25,13 +25,15 @@ void SMALoader::ProcessMultipliers( TimingData &out, const int iRowsPerBeat, con
split( arrayMultiplierExpressions[f], "=", arrayMultiplierValues );
if( arrayMultiplierValues.size() != 2 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #MULTIPLIER value \"%s\" (must have exactly one '='), ignored.",
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid #MULTIPLIER value \"%s\" (must have exactly one '='), ignored.",
arrayMultiplierExpressions[f].c_str() );
continue;
}
const float fComboBeat = RowToBeat( arrayMultiplierValues[0], iRowsPerBeat );
const int iCombos = StringToInt( arrayMultiplierValues[1] );
ComboSegment new_seg( BeatToNoteRow( fComboBeat ), iCombos );
ComboSegment new_seg( fComboBeat, iCombos );
out.AddComboSegment( new_seg );
}
}
@@ -48,23 +50,32 @@ void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam )
if( vs2.size() < 2 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid beats per measure change with %i values.", (int)vs2.size() );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid beats per measure change with %i values.",
static_cast<int>(vs2.size()) );
continue;
}
const float fBeat = StringToFloat( vs2[0] );
TimeSignatureSegment seg( BeatToNoteRow( fBeat ), StringToInt( vs2[1] ), 4 );
TimeSignatureSegment seg( fBeat, StringToInt( vs2[1] ), 4 );
if( fBeat < 0 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f.", fBeat );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid time signature change with beat %f.",
fBeat );
continue;
}
if( seg.GetNum() < 1 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.GetNum() );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid time signature change with beat %f, iNumerator %i.",
fBeat, seg.GetNum() );
continue;
}
@@ -92,7 +103,10 @@ void SMALoader::ProcessSpeeds( TimingData &out, const RString line, const int ro
if( vs2.size() < 3 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with %i values.", (int)vs2.size() );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an speed change with %i values.",
static_cast<int>(vs2.size()) );
continue;
}
@@ -109,13 +123,19 @@ void SMALoader::ProcessSpeeds( TimingData &out, const RString line, const int ro
if( fBeat < 0 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f.", fBeat );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an speed change with beat %f.",
fBeat );
continue;
}
if( seg.GetLength() < 0 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f, length %f.", fBeat, seg.GetLength() );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an speed change with beat %f, length %f.",
fBeat, seg.GetLength() );
continue;
}
@@ -152,7 +172,10 @@ bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
/* Don't use GetMainAndSubTitlesFromFullTitle; that's only for heuristically
* splitting other formats that *don't* natively support #SUBTITLE. */
if( sValueName=="TITLE" )
{
out.m_sMainTitle = sParams[1];
this->SetSongTitle(sParams[1]);
}
else if( sValueName=="SUBTITLE" )
out.m_sSubTitle = sParams[1];
@@ -314,7 +337,10 @@ bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
else if( StringToInt(sParams[1]) > 0 )
out.m_SelectionDisplay = out.SHOW_ALWAYS;
else
LOG->UserLog( "Song file", sPath, "has an unknown #SELECTABLE value, \"%s\"; ignored.", sParams[1].c_str() );
LOG->UserLog("Song file",
sPath,
"has an unknown #SELECTABLE value, \"%s\"; ignored.",
sParams[1].c_str() );
}
else if( sValueName.Left(strlen("BGCHANGES"))=="BGCHANGES" || sValueName=="ANIMATIONS" )
@@ -413,7 +439,10 @@ bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
{
if( iNumParams < 7 )
{
LOG->UserLog( "Song file", sPath, "has %d fields in a #NOTES tag, but should have at least 7.", iNumParams );
LOG->UserLog("Song file",
sPath,
"has %d fields in a #NOTES tag, but should have at least 7.",
iNumParams );
continue;
}
@@ -431,7 +460,10 @@ bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
else if( sValueName=="TIMESIGNATURES" || sValueName=="LEADTRACK" )
;
else
LOG->UserLog( "Song file", sPath, "has an unexpected value named \"%s\".", sValueName.c_str() );
LOG->UserLog("Song file",
sPath,
"has an unexpected value named \"%s\".",
sValueName.c_str() );
}
TidyUpData(out, false);
out.TidyUpData();
+62 -20
View File
@@ -23,10 +23,11 @@ void SSCLoader::ProcessWarps( TimingData &out, const RString sParam, const float
{
vector<RString> arrayWarpValues;
split( arrayWarpExpressions[b], "=", arrayWarpValues );
// XXX: Hard to tell which file caused this.
if( arrayWarpValues.size() != 2 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #WARPS value \"%s\" (must have exactly one '='), ignored.",
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid #WARPS value \"%s\" (must have exactly one '='), ignored.",
arrayWarpExpressions[b].c_str() );
continue;
}
@@ -42,7 +43,10 @@ void SSCLoader::ProcessWarps( TimingData &out, const RString sParam, const float
out.AddWarpSegment( WarpSegment(fBeat, fNewBeat) );
else
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Warp at beat %f, BPM %f.", fBeat, fNewBeat );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid Warp at beat %f, BPM %f.",
fBeat, fNewBeat );
}
}
}
@@ -58,7 +62,9 @@ void SSCLoader::ProcessLabels( TimingData &out, const RString sParam )
split( arrayLabelExpressions[b], "=", arrayLabelValues );
if( arrayLabelValues.size() != 2 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #LABELS value \"%s\" (must have exactly one '='), ignored.",
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid #LABELS value \"%s\" (must have exactly one '='), ignored.",
arrayLabelExpressions[b].c_str() );
continue;
}
@@ -70,7 +76,10 @@ void SSCLoader::ProcessLabels( TimingData &out, const RString sParam )
out.AddLabelSegment( LabelSegment(fBeat, sLabel) );
else
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Label at beat %f called %s.", fBeat, sLabel.c_str() );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid Label at beat %f called %s.",
fBeat, sLabel.c_str() );
}
}
@@ -87,13 +96,15 @@ void SSCLoader::ProcessCombos( TimingData &out, const RString line, const int ro
split( arrayComboExpressions[f], "=", arrayComboValues );
if( arrayComboValues.size() != 2 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #COMBOS value \"%s\" (must have exactly one '='), ignored.",
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid #COMBOS value \"%s\" (must have exactly one '='), ignored.",
arrayComboExpressions[f].c_str() );
continue;
}
const float fComboBeat = StringToFloat( arrayComboValues[0] );
const int iCombos = StringToInt( arrayComboValues[1] );
ComboSegment new_seg( BeatToNoteRow( fComboBeat ), iCombos );
ComboSegment new_seg( fComboBeat, iCombos );
out.AddComboSegment( new_seg );
}
}
@@ -110,7 +121,10 @@ void SSCLoader::ProcessScrolls( TimingData &out, const RString sParam )
if( vs2.size() < 2 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an scroll change with %i values.", (int)vs2.size() );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an scroll change with %i values.",
static_cast<int>(vs2.size()) );
continue;
}
@@ -120,7 +134,10 @@ void SSCLoader::ProcessScrolls( TimingData &out, const RString sParam )
if( fBeat < 0 )
{
LOG->UserLog( "Song file", "(UNKNOWN)", "has an scroll change with beat %f.", fBeat );
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an scroll change with beat %f.",
fBeat );
continue;
}
@@ -166,6 +183,7 @@ bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
else if( sValueName=="TITLE" )
{
out.m_sMainTitle = sParams[1];
this->SetSongTitle(sParams[1]);
}
else if( sValueName=="SUBTITLE" )
@@ -564,21 +582,28 @@ bool SSCLoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool
int iBytes = FILEMAN->GetFileSizeInBytes( sEditFilePath );
if( iBytes > MAX_EDIT_STEPS_SIZE_BYTES )
{
LOG->UserLog( "Edit file", sEditFilePath, "is unreasonably large. It won't be loaded." );
LOG->UserLog("Edit file",
sEditFilePath,
"is unreasonably large. It won't be loaded." );
return false;
}
MsdFile msd;
if( !msd.ReadFile( sEditFilePath, true ) ) // unescape
{
LOG->UserLog( "Edit file", sEditFilePath, "couldn't be opened: %s", msd.GetError().c_str() );
LOG->UserLog("Edit file",
sEditFilePath,
"couldn't be opened: %s", msd.GetError().c_str() );
return false;
}
return LoadEditFromMsd( msd, sEditFilePath, slot, bAddStepsToSong );
}
bool SSCLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong )
bool SSCLoader::LoadEditFromMsd(const MsdFile &msd,
const RString &sEditFilePath,
ProfileSlot slot,
bool bAddStepsToSong )
{
Song* pSong = NULL;
Steps* pNewNotes = NULL;
@@ -608,18 +633,25 @@ bool SSCLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePat
}
RString sSongFullTitle = sParams[1];
this->SetSongTitle(sParams[1]);
sSongFullTitle.Replace( '\\', '/' );
pSong = SONGMAN->FindSong( sSongFullTitle );
if( pSong == NULL )
{
LOG->UserLog( "Edit file", sEditFilePath, "requires a song \"%s\" that isn't present.", sSongFullTitle.c_str() );
LOG->UserLog("Edit file",
sEditFilePath,
"requires a song \"%s\" that isn't present.",
sSongFullTitle.c_str() );
return false;
}
if( pSong->GetNumStepsLoadedFromProfile(slot) >= MAX_EDITS_PER_SONG_PER_PROFILE )
{
LOG->UserLog( "Song file", sSongFullTitle, "already has the maximum number of edits allowed for ProfileSlotP%d.", slot+1 );
LOG->UserLog("Song file",
sSongFullTitle,
"already has the maximum number of edits allowed for ProfileSlotP%d.",
slot+1 );
return false;
}
}
@@ -667,8 +699,8 @@ bool SSCLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePat
{
RadarValues v[NUM_PLAYERS];
FOREACH_PlayerNumber( pn )
FOREACH_ENUM( RadarCategory, rc )
v[pn][rc] = StringToFloat( saValues[pn*NUM_RadarCategory + rc] );
FOREACH_ENUM( RadarCategory, rc )
v[pn][rc] = StringToFloat( saValues[pn*NUM_RadarCategory + rc] );
pNewNotes->SetCachedRadarValues( v );
}
bSSCFormat = true;
@@ -744,13 +776,18 @@ bool SSCLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePat
{
if( pSong == NULL )
{
LOG->UserLog( "Edit file", sEditFilePath, "doesn't have a #SONG tag preceeding the first #NOTES tag." );
LOG->UserLog("Edit file",
sEditFilePath,
"doesn't have a #SONG tag preceeding the first #NOTES tag." );
return false;
}
if ( !bSSCFormat && iNumParams < 7 )
{
LOG->UserLog( "Edit file", sEditFilePath, "has %d fields in a #NOTES tag, but should have at least 7.", iNumParams );
LOG->UserLog("Edit file",
sEditFilePath,
"has %d fields in a #NOTES tag, but should have at least 7.",
iNumParams );
continue;
}
@@ -785,7 +822,9 @@ bool SSCLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePat
if( pSong->IsEditAlreadyLoaded(pNewNotes) )
{
LOG->UserLog( "Edit file", sEditFilePath, "is a duplicate of another edit that was already loaded." );
LOG->UserLog("Edit file",
sEditFilePath,
"is a duplicate of another edit that was already loaded." );
SAFE_DELETE( pNewNotes );
return false;
}
@@ -795,7 +834,10 @@ bool SSCLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePat
}
else
{
LOG->UserLog( "Edit file", sEditFilePath, "has an unexpected value \"%s\".", sValueName.c_str() );
LOG->UserLog("Edit file",
sEditFilePath,
"has an unexpected value \"%s\".",
sValueName.c_str() );
}
}