Improved PatternMerger JSON and CSV outputs to be more usefull

This commit is contained in:
PatrickvL 2017-02-09 17:14:03 +01:00
parent ce4ab71582
commit 4131f5e43b

View file

@ -16,8 +16,8 @@ const
HexByte_Length = 2;
Version_Length = 4; // 3912, etc
FirstPattern_Offset = 1;
FirstPattern_Length = 32 * HexByte_Length;
StartPattern_Offset = 1;
StartPattern_Length = 32 * HexByte_Length;
CRC_Offset = 66;
CRC_Length = HexByte_Length + Space_Length + (2 * HexByte_Length);
Length_Offset = 74;
@ -45,6 +45,23 @@ begin
WriteLn;
end;
function Hex2ToByte(const aStr: string): Byte;
begin
Assert(Length(aStr) >= 2, 'Two (2) input characters required');
HexToBin(PChar(aStr), @Result, 2);
end;
function Hex4ToWord(const aStr: string): Word;
var
Buffer: array [0..1] of Byte;
begin
Assert(Length(aStr) >= 4, 'Four (4) input characters required');
HexToBin(PChar(aStr), @Buffer[0], 4);
Result := (Buffer[0] * 256) + Buffer[1];
end;
var
PatternsPath: string;
OuputFormat: TOuputFormat;
@ -57,12 +74,12 @@ var
VersionAndLibStr: string;
Line: string;
p: Integer;
FirstPatternStr: string;
StartPatternStr: string;
CRCStr: string;
SymbolStr: string;
LengthStr: string;
ReferencesStr: string;
SecondPatternStr: string;
TrailingPatternStr: string;
begin
try
if ParamCount < 2 then
@ -113,7 +130,7 @@ begin
ofCSV:
VersionAndLibStr := Comma + VersionStr + Comma + LibStr + Comma;
ofJson:
VersionAndLibStr := '","version":' + VersionStr + ',"lib":"' + LibStr + '","length":"';
VersionAndLibStr := '","version":' + VersionStr + ',"lib":"' + LibStr + '","length":';
end;
for i := 0 to Input.Count - 1 do
@ -140,76 +157,104 @@ begin
Continue;
// Decompose line into it's parts :
FirstPatternStr := Copy(Line, FirstPattern_Offset, FirstPattern_Length);
CRCStr := Copy(Line, CRC_Offset, CRC_Length); // TODO : Should we split up CRC into CRCLength and CRCValue?
LengthStr := Copy(Line, Length_Offset, Length_Length); // TODO : Should we convert length from hexadecimal into decimal?
StartPatternStr := Copy(Line, StartPattern_Offset, StartPattern_Length);
CRCStr := Copy(Line, CRC_Offset, CRC_Length); // TODO : split up CRC into CRCLength and CRCValue
LengthStr := Copy(Line, Length_Offset, Length_Length);
ReferencesStr := '';
p := Pos(Space, Line, SymbolName_Offset);
if p > 0 then
begin
SymbolStr := Copy(Line, SymbolName_Offset, {SymbolName_Length=}p - SymbolName_Offset);
SecondPatternStr := Copy(Line, p + Space_Length, MaxInt);
// Does the line contain xrefs before the second pattern ?
p := Length(SecondPatternStr);
while (p > 0) and (SecondPatternStr[p] <> Carret) do
TrailingPatternStr := Copy(Line, p + Space_Length, MaxInt);
// Does the line contain xrefs before the trailing pattern ?
p := Length(TrailingPatternStr);
while (p > 0) and (TrailingPatternStr[p] <> Carret) do
Dec(p);
// Did we find a carret?
if p > 0 then
begin
// Goto next space
p := Pos(Space, SecondPatternStr, p);
p := Pos(Space, TrailingPatternStr, p);
Assert(p > 0);
if Pos(Space, SecondPatternStr, p + Space_Length) > 0 then
if Pos(Space, TrailingPatternStr, p + Space_Length) > 0 then
begin
p := Pos(Space, SecondPatternStr, p + Space_Length);
ReferencesStr := Copy(SecondPatternStr, 1, p - Space_Length);
Delete({var}SecondPatternStr, 1, p + Space_Length);
p := Pos(Space, TrailingPatternStr, p + Space_Length);
ReferencesStr := Copy(TrailingPatternStr, 1, p - Space_Length);
Delete({var}TrailingPatternStr, 1, p + Space_Length);
end
else
begin
ReferencesStr := SecondPatternStr;
SecondPatternStr := '';
ReferencesStr := TrailingPatternStr;
TrailingPatternStr := '';
end;
end;
end
else
begin
SymbolStr := Copy(Line, SymbolName_Offset, MaxInt);
SecondPatternStr := '';
TrailingPatternStr := '';
end;
// Recompose and format output line :
case OuputFormat of
ofPAT:
begin
Line := SymbolStr + VersionAndLibStr + LengthStr + Space + FirstPatternStr + Space + CRCStr;
Line := SymbolStr + VersionAndLibStr + LengthStr + Space + StartPatternStr + Space + CRCStr;
// PAT must not append trailing spaces
if SecondPatternStr <> '' then
Line := Line + Space + SecondPatternStr;
if TrailingPatternStr <> '' then
Line := Line + Space + TrailingPatternStr;
if ReferencesStr <> '' then
Line := Line + Space + ReferencesStr;
end;
ofCSV:
begin
// Convert length from hex to integer :
LengthStr := IntToStr(Hex4ToWord(LengthStr));
// Convert CRCLength from hex to integer, separate CRCLength and CRCValue by a comma :
p := Hex2ToByte(CRCStr);
CRCStr := IntToStr(p) + ',' + Copy(CRCStr, 4, 4);
// CSV allows empty values between commas
Line := SymbolStr + VersionAndLibStr + LengthStr + Comma + FirstPatternStr + Comma + CRCStr + Comma + SecondPatternStr + Comma + ReferencesStr;
Line := SymbolStr + VersionAndLibStr + LengthStr + Comma + StartPatternStr + Comma + CRCStr + Comma + TrailingPatternStr + Comma + ReferencesStr;
end;
ofJson:
begin
// Note : JSON allows absent values and supports integer values.
// Get the length of the starting pattern, and trim it when possible :
p := Hex4ToWord(LengthStr);
if p * HexByte_Length < StartPattern_Length then
begin
SetLength(StartPatternStr, p * HexByte_Length);
Assert(TrailingPatternStr = '', 'Trailing pattern shouldn''t be set when length is less than 32!');
end;
Line := '{"symbol":"' + SymbolStr +
VersionAndLibStr + LengthStr +
'","first_pattern":"' + FirstPatternStr +
'","crc":"' + CRCStr + '"';
// JSON allows absent values :
if SecondPatternStr <> '' then
Line := Line + ',"second_pattern":"' + SecondPatternStr + '"';
VersionAndLibStr + IntToStr(p) +
',"start_pattern":"' + StartPatternStr + '"';
// The CRC might be useless if there's no trailing pattern :
if (CRCStr <> '00 0000') or (TrailingPatternStr <> '') then
begin
// render CRCLength as a separate integer
p := Hex2ToByte(CRCStr);
Line := Line + ',"crc_length":' + IntToStr(p);
if p > 0 then
// only when needed, render CRCValue as a HexString
Line := Line + ',"crc_value":"' + Copy(CRCStr, 4, 4) + '"';
end;
if TrailingPatternStr <> '' then
Line := Line + ',"trailing_pattern":"' + TrailingPatternStr + '"';
if ReferencesStr <> '' then
begin
// convert references into an array
ReferencesStr := StringReplace(Space + ReferencesStr, Space + Carret, '"},{"offset":"', [rfReplaceAll]);
// TODO : should we convert 'R'elative/'D'irect indicators into separate values?
// TODO : render xref offsets as integers instead of hexadecimal strings
// TODO : convert 'R'elative/'D'irect indicators into separate values
ReferencesStr := StringReplace(ReferencesStr, Space, '","xref":"', [rfReplaceAll]);
Line := Line + ',"references":[' + Copy(ReferencesStr, 4, MaxInt) + '"}]';
end;
@ -234,7 +279,7 @@ begin
ofCSV:
begin
// Insert csv header line :
Output.Insert(0, 'Symbol,Version,Lib,Length,FirstPattern,CRC,SecondPattern,References');
Output.Insert(0, 'Symbol,Version,Lib,Length,StartPattern,CRCLength,CRCValue,TrailingPattern,References');
Output.SaveToFile(PatternsPath + 'all.csv');
end;
ofJSON: