Fix ParentablePath issues; fix parse logging

This commit is contained in:
Matt Nadareski
2020-09-21 13:04:11 -07:00
parent 07066c2299
commit a04a3485ef
20 changed files with 517 additions and 388 deletions

View File

@@ -59,13 +59,6 @@ namespace SabreTools.Library.DatFiles
{ {
// Get the current line, split and parse // Get the current line, split and parse
svr.ReadNextLine(); svr.ReadNextLine();
}
catch (InvalidDataException ex)
{
Globals.Logger.Error(ex, $"Malformed line found in '{filename}' at line {svr.LineNumber}");
if (throwOnError) throw ex;
continue;
}
Rom rom = new Rom Rom rom = new Rom
{ {
@@ -107,6 +100,17 @@ namespace SabreTools.Library.DatFiles
// Now process and add the rom // Now process and add the rom
ParseAddHelper(rom); ParseAddHelper(rom);
} }
catch (Exception ex)
{
string message = $"'{filename}' - There was an error parsing line {svr.LineNumber} '{svr.CurrentLine}'";
Globals.Logger.Error(ex, message);
if (throwOnError)
{
svr.Dispose();
throw new Exception(message, ex);
}
}
}
svr.Dispose(); svr.Dispose();
} }

View File

@@ -53,6 +53,8 @@ namespace SabreTools.Library.DatFiles
}; };
while (!cmpr.EndOfStream) while (!cmpr.EndOfStream)
{
try
{ {
cmpr.ReadNextLine(); cmpr.ReadNextLine();
@@ -83,6 +85,17 @@ namespace SabreTools.Library.DatFiles
break; break;
} }
} }
catch (Exception ex)
{
string message = $"'{filename}' - There was an error parsing line {cmpr.LineNumber} '{cmpr.CurrentLine}'";
Globals.Logger.Error(ex, message);
if (throwOnError)
{
cmpr.Dispose();
throw new Exception(message, ex);
}
}
}
cmpr.Dispose(); cmpr.Dispose();
} }

View File

@@ -1802,10 +1802,11 @@ namespace SabreTools.Library.DatFiles
/// Create a DatFile and parse a file into it /// Create a DatFile and parse a file into it
/// </summary> /// </summary>
/// <param name="filename">Name of the file to be parsed</param> /// <param name="filename">Name of the file to be parsed</param>
public static DatFile CreateAndParse(string filename) /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
public static DatFile CreateAndParse(string filename, bool throwOnError = false)
{ {
DatFile datFile = Create(); DatFile datFile = Create();
datFile.Parse(new ParentablePath(filename)); datFile.Parse(new ParentablePath(filename), throwOnError: throwOnError);
return datFile; return datFile;
} }
@@ -1833,22 +1834,22 @@ namespace SabreTools.Library.DatFiles
/// <summary> /// <summary>
/// Parse a DAT and return all found games and roms within /// Parse a DAT and return all found games and roms within
/// </summary> /// </summary>
/// <param name="filename">Name of the file to be parsed</param> /// <param name="input">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param> /// <param name="indexId">Index ID for the DAT</param>
/// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
/// <param name="keepext">True if original extension should be kept, false otherwise (default)</param> /// <param name="keepext">True if original extension should be kept, false otherwise (default)</param>
/// <param name="quotes">True if quotes are assumed in supported types (default), false otherwise</param> /// <param name="quotes">True if quotes are assumed in supported types (default), false otherwise</param>
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param> /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
public void Parse( public void Parse(
ParentablePath filename, ParentablePath input,
int indexId = 0, int indexId = 0,
bool keep = false, bool keep = false,
bool keepext = false, bool keepext = false,
bool quotes = true, bool quotes = true,
bool throwOnError = false) bool throwOnError = true)
{ {
// Get the current path from the filename // Get the current path from the filename
string currentPath = filename.CurrentPath; string currentPath = input.CurrentPath;
// Check the file extension first as a safeguard // Check the file extension first as a safeguard
if (!PathExtensions.HasValidDatExtension(currentPath)) if (!PathExtensions.HasValidDatExtension(currentPath))
@@ -1868,7 +1869,7 @@ namespace SabreTools.Library.DatFiles
} }
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Error(ex, $"Error with file '{filename}'"); Globals.Logger.Error(ex, $"Error with file '{currentPath}'");
if (throwOnError) throw ex; if (throwOnError) throw ex;
} }
} }

View File

@@ -42,6 +42,8 @@ namespace SabreTools.Library.DatFiles
}; };
while (!cmpr.EndOfStream) while (!cmpr.EndOfStream)
{
try
{ {
cmpr.ReadNextLine(); cmpr.ReadNextLine();
@@ -66,6 +68,17 @@ namespace SabreTools.Library.DatFiles
break; break;
} }
} }
catch (Exception ex)
{
string message = $"'{filename}' - There was an error parsing line {cmpr.LineNumber} '{cmpr.CurrentLine}'";
Globals.Logger.Error(ex, message);
if (throwOnError)
{
cmpr.Dispose();
throw new Exception(message, ex);
}
}
}
cmpr.Dispose(); cmpr.Dispose();
} }

View File

@@ -33,11 +33,14 @@ namespace SabreTools.Library.DatFiles
/// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param> /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false) protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
{ {
// TODO: Use SeparatedValueReader
// Open a file reader // Open a file reader
Encoding enc = FileExtensions.GetEncoding(filename); Encoding enc = FileExtensions.GetEncoding(filename);
StreamReader sr = new StreamReader(FileExtensions.TryOpenRead(filename), enc); StreamReader sr = new StreamReader(FileExtensions.TryOpenRead(filename), enc);
while (!sr.EndOfStream) while (!sr.EndOfStream)
{
try
{ {
string line = sr.ReadLine(); string line = sr.ReadLine();
@@ -79,6 +82,17 @@ namespace SabreTools.Library.DatFiles
// Now process and add the rom // Now process and add the rom
ParseAddHelper(rom); ParseAddHelper(rom);
} }
catch (Exception ex)
{
string message = $"'{filename}' - There was an error parsing at position {sr.BaseStream.Position}";
Globals.Logger.Error(ex, message);
if (throwOnError)
{
sr.Dispose();
throw new Exception(message, ex);
}
}
}
sr.Dispose(); sr.Dispose();
} }

View File

@@ -42,6 +42,8 @@ namespace SabreTools.Library.DatFiles
StreamReader sr = new StreamReader(FileExtensions.TryOpenRead(filename), enc); StreamReader sr = new StreamReader(FileExtensions.TryOpenRead(filename), enc);
while (!sr.EndOfStream) while (!sr.EndOfStream)
{
try
{ {
string line = sr.ReadLine(); string line = sr.ReadLine();
@@ -94,6 +96,17 @@ namespace SabreTools.Library.DatFiles
// Now process and add the rom // Now process and add the rom
ParseAddHelper(rom); ParseAddHelper(rom);
} }
catch (Exception ex)
{
string message = $"'{filename}' - There was an error parsing at position {sr.BaseStream.Position}";
Globals.Logger.Error(ex, message);
if (throwOnError)
{
sr.Dispose();
throw new Exception(message, ex);
}
}
}
sr.Dispose(); sr.Dispose();
} }

View File

@@ -1410,13 +1410,13 @@ namespace SabreTools.Library.DatFiles
dirStats.ResetStatistics(); dirStats.ResetStatistics();
} }
Globals.Logger.Verbose($"Beginning stat collection for '{file}'", false); Globals.Logger.Verbose($"Beginning stat collection for '{file.CurrentPath}'", false);
List<string> games = new List<string>(); List<string> games = new List<string>();
DatFile datdata = DatFile.CreateAndParse(file.CurrentPath); DatFile datdata = DatFile.CreateAndParse(file.CurrentPath);
datdata.Items.BucketBy(Field.Machine_Name, DedupeType.None, norename: true); datdata.Items.BucketBy(Field.Machine_Name, DedupeType.None, norename: true);
// Output single DAT stats (if asked) // Output single DAT stats (if asked)
Globals.Logger.User($"Adding stats for file '{file}'\n", false); Globals.Logger.User($"Adding stats for file '{file.CurrentPath}'\n", false);
if (single) if (single)
{ {
reports.ForEach(report => report.ReplaceStatistics(datdata.Header.FileName, datdata.Items.Keys.Count, datdata.Items)); reports.ForEach(report => report.ReplaceStatistics(datdata.Header.FileName, datdata.Items.Keys.Count, datdata.Items));

View File

@@ -49,6 +49,8 @@ namespace SabreTools.Library.DatFiles
string gamename = string.Empty; string gamename = string.Empty;
while (!sr.EndOfStream) while (!sr.EndOfStream)
{
try
{ {
string line = sr.ReadLine().Trim(); string line = sr.ReadLine().Trim();
@@ -248,6 +250,17 @@ namespace SabreTools.Library.DatFiles
} }
} }
} }
catch (Exception ex)
{
string message = $"'{filename}' - There was an error parsing at position {sr.BaseStream.Position}";
Globals.Logger.Error(ex, message);
if (throwOnError)
{
sr.Dispose();
throw new Exception(message, ex);
}
}
}
} }
/// <inheritdoc/> /// <inheritdoc/>

View File

@@ -90,8 +90,12 @@ namespace SabreTools.Library.DatFiles
} }
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}"); Globals.Logger.Warning(ex, $"Exception found while parsing '{filename}'");
if (throwOnError) throw ex; if (throwOnError)
{
xtr.Dispose();
throw ex;
}
// For XML errors, just skip the affected node // For XML errors, just skip the affected node
xtr?.Read(); xtr?.Read();

View File

@@ -107,8 +107,12 @@ namespace SabreTools.Library.DatFiles
} }
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}"); Globals.Logger.Warning(ex, $"Exception found while parsing '{filename}'");
if (throwOnError) throw ex; if (throwOnError)
{
xtr.Dispose();
throw ex;
}
// For XML errors, just skip the affected node // For XML errors, just skip the affected node
xtr?.Read(); xtr?.Read();

View File

@@ -78,8 +78,12 @@ namespace SabreTools.Library.DatFiles
} }
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}"); Globals.Logger.Warning(ex, $"Exception found while parsing '{filename}'");
if (throwOnError) throw ex; if (throwOnError)
{
xtr.Dispose();
throw ex;
}
// For XML errors, just skip the affected node // For XML errors, just skip the affected node
xtr?.Read(); xtr?.Read();

View File

@@ -80,8 +80,12 @@ namespace SabreTools.Library.DatFiles
} }
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}"); Globals.Logger.Warning(ex, $"Exception found while parsing '{filename}'");
if (throwOnError) throw ex; if (throwOnError)
{
xtr.Dispose();
throw ex;
}
// For XML errors, just skip the affected node // For XML errors, just skip the affected node
xtr?.Read(); xtr?.Read();

View File

@@ -84,8 +84,13 @@ namespace SabreTools.Library.DatFiles
} }
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}"); string message = $"'{filename}' - There was an error parsing line {ir.LineNumber} '{ir.CurrentLine}'";
if (throwOnError) throw ex; Globals.Logger.Error(ex, message);
if (throwOnError)
{
ir.Dispose();
throw new Exception(message, ex);
}
} }
ir.Dispose(); ir.Dispose();
@@ -304,7 +309,7 @@ namespace SabreTools.Library.DatFiles
} }
// Roms are not valid row formats, usually // Roms are not valid row formats, usually
string line = reader.Line; string line = reader.CurrentLine;
// If we don't have a valid game, keep reading // If we don't have a valid game, keep reading
if (!line.StartsWith("¬")) if (!line.StartsWith("¬"))

View File

@@ -77,8 +77,12 @@ namespace SabreTools.Library.DatFiles
} }
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}"); Globals.Logger.Warning(ex, $"Exception found while parsing '{filename}'");
if (throwOnError) throw ex; if (throwOnError)
{
xtr.Dispose();
throw ex;
}
// For XML errors, just skip the affected node // For XML errors, just skip the affected node
xtr?.Read(); xtr?.Read();

View File

@@ -65,8 +65,14 @@ namespace SabreTools.Library.DatFiles
} }
catch (InvalidDataException ex) catch (InvalidDataException ex)
{ {
Globals.Logger.Warning($"Malformed line found in '{filename}' at line {svr.LineNumber}"); string message = $"'{filename}' - There was an error parsing line {svr.LineNumber} '{svr.CurrentLine}'";
if (throwOnError) throw ex; Globals.Logger.Error(ex, message);
if (throwOnError)
{
svr.Dispose();
throw new Exception(message, ex);
}
continue; continue;
} }

View File

@@ -81,8 +81,12 @@ namespace SabreTools.Library.DatFiles
} }
catch (Exception ex) catch (Exception ex)
{ {
Globals.Logger.Warning($"Exception found while parsing '{filename}': {ex}"); Globals.Logger.Warning(ex, $"Exception found while parsing '{filename}'");
if (throwOnError) throw ex; if (throwOnError)
{
xtr.Dispose();
throw ex;
}
// For XML errors, just skip the affected node // For XML errors, just skip the affected node
xtr?.Read(); xtr?.Read();

View File

@@ -74,7 +74,7 @@ namespace SabreTools.Library.Filtering
{ {
// Get the key and value // Get the key and value
string key = ir.Section; string key = ir.Section;
string value = ir.Line.Trim(); string value = ir.CurrentLine.Trim();
// If the section is "ROOT_FOLDER", then we use the value "true" instead. // If the section is "ROOT_FOLDER", then we use the value "true" instead.
// This is done because some INI files use the name of the file as the // This is done because some INI files use the name of the file as the

View File

@@ -16,6 +16,16 @@ namespace SabreTools.Library.IO
/// </summary> /// </summary>
private StreamReader sr; private StreamReader sr;
/// <summary>
/// Contents of the current line, unprocessed
/// </summary>
public string CurrentLine { get; private set; } = string.Empty;
/// <summary>
/// Get the current line number
/// </summary>
public long LineNumber { get; private set; } = 0;
/// <summary> /// <summary>
/// Get if at end of stream /// Get if at end of stream
/// </summary> /// </summary>
@@ -74,7 +84,6 @@ namespace SabreTools.Library.IO
public ClrMameProReader(string filename) public ClrMameProReader(string filename)
{ {
sr = new StreamReader(filename); sr = new StreamReader(filename);
DosCenter = true;
} }
/// <summary> /// <summary>
@@ -83,7 +92,6 @@ namespace SabreTools.Library.IO
public ClrMameProReader(Stream stream, Encoding encoding) public ClrMameProReader(Stream stream, Encoding encoding)
{ {
sr = new StreamReader(stream, encoding); sr = new StreamReader(stream, encoding);
DosCenter = true;
} }
/// <summary> /// <summary>
@@ -94,8 +102,11 @@ namespace SabreTools.Library.IO
if (!(sr.BaseStream?.CanRead ?? false) || sr.EndOfStream) if (!(sr.BaseStream?.CanRead ?? false) || sr.EndOfStream)
return false; return false;
string line = sr.ReadLine().Trim(); CurrentLine = sr.ReadLine().Trim();
ProcessLine(line); LineNumber++;
// TODO: Act like IniReader here
ProcessLine(CurrentLine);
return true; return true;
} }

View File

@@ -30,9 +30,14 @@ namespace SabreTools.Library.IO
public KeyValuePair<string, string>? KeyValuePair { get; private set; } = null; public KeyValuePair<string, string>? KeyValuePair { get; private set; } = null;
/// <summary> /// <summary>
/// Contents of the currently read line /// Contents of the current line, unprocessed
/// </summary> /// </summary>
public string Line { get; private set; } = string.Empty; public string CurrentLine { get; private set; } = string.Empty;
/// <summary>
/// Get the current line number
/// </summary>
public long LineNumber { get; private set; } = 0;
/// <summary> /// <summary>
/// Current row type /// Current row type
@@ -73,7 +78,8 @@ namespace SabreTools.Library.IO
if (!(sr.BaseStream?.CanRead ?? false) || sr.EndOfStream) if (!(sr.BaseStream?.CanRead ?? false) || sr.EndOfStream)
return false; return false;
Line = sr.ReadLine().Trim(); CurrentLine = sr.ReadLine().Trim();
LineNumber++;
ProcessLine(); ProcessLine();
return true; return true;
} }
@@ -84,25 +90,25 @@ namespace SabreTools.Library.IO
private void ProcessLine() private void ProcessLine()
{ {
// Comment // Comment
if (Line.StartsWith(";")) if (CurrentLine.StartsWith(";"))
{ {
KeyValuePair = null; KeyValuePair = null;
RowType = IniRowType.Comment; RowType = IniRowType.Comment;
} }
// Section // Section
else if (Line.StartsWith("[") && Line.EndsWith("]")) else if (CurrentLine.StartsWith("[") && CurrentLine.EndsWith("]"))
{ {
KeyValuePair = null; KeyValuePair = null;
RowType = IniRowType.SectionHeader; RowType = IniRowType.SectionHeader;
Section = Line.TrimStart('[').TrimEnd(']'); Section = CurrentLine.TrimStart('[').TrimEnd(']');
} }
// KeyValuePair // KeyValuePair
else if (Line.Contains("=")) else if (CurrentLine.Contains("="))
{ {
// Split the line by '=' for key-value pairs // Split the line by '=' for key-value pairs
string[] data = Line.Split('='); string[] data = CurrentLine.Split('=');
// If the value field contains an '=', we need to put them back in // If the value field contains an '=', we need to put them back in
string key = data[0].Trim(); string key = data[0].Trim();
@@ -113,10 +119,10 @@ namespace SabreTools.Library.IO
} }
// Empty // Empty
else if (string.IsNullOrEmpty(Line)) else if (string.IsNullOrEmpty(CurrentLine))
{ {
KeyValuePair = null; KeyValuePair = null;
Line = string.Empty; CurrentLine = string.Empty;
RowType = IniRowType.None; RowType = IniRowType.None;
} }
@@ -127,7 +133,7 @@ namespace SabreTools.Library.IO
RowType = IniRowType.Invalid; RowType = IniRowType.Invalid;
if (ValidateRows) if (ValidateRows)
throw new InvalidDataException($"Invalid INI row found, cannot continue: {Line}"); throw new InvalidDataException($"Invalid INI row found, cannot continue: {CurrentLine}");
} }
} }

View File

@@ -30,6 +30,16 @@ namespace SabreTools.Library.IO
} }
} }
/// <summary>
/// Contents of the current line, unprocessed
/// </summary>
public string CurrentLine { get; private set; } = string.Empty;
/// <summary>
/// Get the current line number
/// </summary>
public long LineNumber { get; private set; } = 0;
/// <summary> /// <summary>
/// Assume the first row is a header /// Assume the first row is a header
/// </summary> /// </summary>
@@ -45,11 +55,6 @@ namespace SabreTools.Library.IO
/// </summary> /// </summary>
public List<string> Line { get; private set; } = null; public List<string> Line { get; private set; } = null;
/// <summary>
/// Get the current line number
/// </summary>
public long LineNumber { get; private set; } = -1;
/// <summary> /// <summary>
/// Assume that values are wrapped in quotes /// Assume that values are wrapped in quotes
/// </summary> /// </summary>
@@ -104,6 +109,7 @@ namespace SabreTools.Library.IO
return false; return false;
string fullLine = sr.ReadLine(); string fullLine = sr.ReadLine();
CurrentLine = fullLine;
LineNumber++; LineNumber++;
// If we have quotes, we need to split specially // If we have quotes, we need to split specially