Skip to content

Commit 213e14e

Browse files
authored
WI #1845 Add .xmldiag format for error output in CLI (#1862)
1 parent aceadd0 commit 213e14e

File tree

10 files changed

+181
-8
lines changed

10 files changed

+181
-8
lines changed

CLI/src/CLI.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,19 @@ internal static ReturnCode runOnce(TypeCobolConfiguration config)
4545
File.AppendAllText(config.LogFile ?? TypeCobolConfiguration.DefaultLogFileName, debugLine);
4646
Console.WriteLine(debugLine);
4747
TextWriter textWriter = config.ErrorFile == null ? Console.Error : File.CreateText(config.ErrorFile);
48-
AbstractErrorWriter errorWriter = config.IsErrorXML ? (AbstractErrorWriter) new XMLWriter(textWriter) : new ConsoleWriter(textWriter);
48+
AbstractErrorWriter errorWriter;
49+
switch (Path.GetExtension(config.ErrorFile)?.ToLower())
50+
{
51+
case ".xml":
52+
errorWriter = new XMLWriter(textWriter);
53+
break;
54+
case ".xmldiag":
55+
errorWriter = new XmlDiagWriter(textWriter);
56+
break;
57+
default:
58+
errorWriter = new ConsoleWriter(textWriter);
59+
break;
60+
}
4961
errorWriter.Outputs = config.OutputFiles;
5062

5163
ReturnCode returnCode;

CLI/src/Writer.cs

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ private int GenerateNumber()
6262
public abstract void FlushAndClose();
6363
}
6464

65-
6665
public class XMLWriter : AbstractErrorWriter {
6766
private XmlWriter writer;
6867

@@ -161,7 +160,6 @@ private static string AsIBMSuffix(int severity) {
161160
}
162161
}
163162

164-
165163
public class ConsoleWriter : AbstractErrorWriter {
166164
private System.IO.TextWriter writer;
167165

@@ -197,4 +195,83 @@ public override void FlushAndClose() {
197195
writer.Close();
198196
}
199197
}
200-
}
198+
199+
public class XmlDiagWriter : AbstractErrorWriter
200+
{
201+
private readonly XmlWriter _xmlWriter;
202+
203+
public XmlDiagWriter(TextWriter textWriter)
204+
{
205+
var settings = new XmlWriterSettings
206+
{
207+
Indent = true
208+
};
209+
_xmlWriter = XmlWriter.Create(textWriter, settings);
210+
}
211+
212+
public override void Write(ReturnCode returnCode)
213+
{
214+
_xmlWriter.WriteStartDocument();
215+
_xmlWriter.WriteStartElement("build");
216+
_xmlWriter.WriteAttributeString("return-code", returnCode.ToString());
217+
WriteFileTable();
218+
WriteDiagnostics();
219+
_xmlWriter.WriteEndElement();
220+
_xmlWriter.WriteEndDocument();
221+
}
222+
223+
private void WriteFileTable()
224+
{
225+
_xmlWriter.WriteStartElement("filetable");
226+
foreach (var input in Inputs)
227+
{
228+
_xmlWriter.WriteStartElement("file");
229+
_xmlWriter.WriteAttributeString("index", input.Value);
230+
_xmlWriter.WriteAttributeString("path", input.Key);
231+
_xmlWriter.WriteEndElement();
232+
}
233+
_xmlWriter.WriteEndElement();
234+
}
235+
236+
private void WriteDiagnostics()
237+
{
238+
_xmlWriter.WriteStartElement("diagnostics");
239+
foreach (var error in Errors)
240+
{
241+
string fileIndex = Inputs[error.Key];
242+
foreach (var diagnostic in error.Value)
243+
{
244+
_xmlWriter.WriteStartElement("diagnostic");
245+
_xmlWriter.WriteAttributeString("file-index", fileIndex);
246+
247+
//range
248+
_xmlWriter.WriteStartElement("range");
249+
_xmlWriter.WriteAttributeString("line-start", diagnostic.Line.ToString());
250+
_xmlWriter.WriteAttributeString("column-start", diagnostic.ColumnStart.ToString());
251+
_xmlWriter.WriteAttributeString("line-end", diagnostic.Line.ToString());
252+
_xmlWriter.WriteAttributeString("column-end", diagnostic.ColumnEnd.ToString());
253+
_xmlWriter.WriteEndElement();
254+
255+
//message
256+
_xmlWriter.WriteElementString("message", diagnostic.Message);
257+
258+
//info
259+
_xmlWriter.WriteStartElement("info");
260+
_xmlWriter.WriteAttributeString("severity", diagnostic.Info.Severity.ToString());
261+
_xmlWriter.WriteAttributeString("code", diagnostic.Info.Code.ToString());
262+
_xmlWriter.WriteAttributeString("source", diagnostic.Info.ReferenceText);
263+
_xmlWriter.WriteEndElement();
264+
265+
_xmlWriter.WriteEndElement();
266+
}
267+
}
268+
_xmlWriter.WriteEndElement();
269+
}
270+
271+
public override void FlushAndClose()
272+
{
273+
_xmlWriter.Flush();
274+
_xmlWriter.Close();
275+
}
276+
}
277+
}

CLI/test/CLITest.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,15 @@ public void TestMassGeneration()
340340
CLITestHelper.Test("mass_generation_dependent_programs_2", ReturnCode.ParsingDiagnostics);
341341
}
342342

343+
/// <summary>
344+
/// This is a duplicate of 'mass_generation_dependent_programs_2' but with alternate .xmldiag error format.
345+
/// </summary>
346+
[TestMethod]
347+
public void TestXmlDiagFormat()
348+
{
349+
CLITestHelper.Test("mass_generation_xmldiagformat", ReturnCode.ParsingDiagnostics);
350+
}
351+
343352
/// <summary>
344353
/// Test override of UTF-8 encoding for RDZ format.
345354
/// </summary>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-i input\DVZZPGM1.tcbl -i input\DVZZPGM2.tcbl -i input\DVZZPGM3.tcbl -o output\DVZZPGM1.cbl -o output\DVZZPGM2.cbl -o output\DVZZPGM3.cbl -d output\error.xmldiag
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
IDENTIFICATION DIVISION.
2+
PROGRAM-ID. DVZZPGM1.
3+
DATA DIVISION.
4+
WORKING-STORAGE SECTION.
5+
01 str-message TYPE DVZZPGM2::Type1.
6+
procedure division.
7+
DISPLAY str-message::var1
8+
.
9+
END PROGRAM DVZZPGM1.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
IDENTIFICATION DIVISION.
2+
PROGRAM-ID. DVZZPGM2.
3+
DATA DIVISION.
4+
WORKING-STORAGE SECTION.
5+
*Using voluntarily wrong syntax to create an invalid pgm
6+
01 Type1 %typedef% strict public.
7+
05 var1 PIC X(20).
8+
procedure division.
9+
goback
10+
.
11+
END PROGRAM DVZZPGM2.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
IDENTIFICATION DIVISION.
2+
PROGRAM-ID. DVZZPGM3.
3+
DATA DIVISION.
4+
WORKING-STORAGE SECTION.
5+
01 var1 PIC 9 VALUE '3'.
6+
7+
procedure division.
8+
display "Inside PGM" var1
9+
goback
10+
.
11+
END PROGRAM DVZZPGM3.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
*TypeCobol_Version:0.1(alpha)
2+
IDENTIFICATION DIVISION.
3+
PROGRAM-ID. DVZZPGM3.
4+
DATA DIVISION.
5+
WORKING-STORAGE SECTION.
6+
01 var1 PIC 9 VALUE '3'.
7+
8+
procedure division.
9+
display "Inside PGM" var1
10+
goback
11+
.
12+
END PROGRAM DVZZPGM3.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<build return-code="ParsingDiagnostics">
3+
<filetable>
4+
<file index="1" path="input\DVZZPGM1.tcbl" />
5+
<file index="2" path="input\DVZZPGM2.tcbl" />
6+
<file index="3" path="input\DVZZPGM3.tcbl" />
7+
</filetable>
8+
<diagnostics>
9+
<diagnostic file-index="1">
10+
<range line-start="5" column-start="8" line-end="5" column-end="43" />
11+
<message>Semantic error: TYPE 'DVZZPGM2.Type1' is not referenced</message>
12+
<info severity="Error" code="30" source="Page" />
13+
</diagnostic>
14+
<diagnostic file-index="1">
15+
<range line-start="7" column-start="33" line-end="7" column-end="36" />
16+
<message>Semantic error: Symbol str-message.var1 is not referenced</message>
17+
<info severity="Error" code="30" source="Page" />
18+
</diagnostic>
19+
<diagnostic file-index="2">
20+
<range line-start="6" column-start="18" line-end="6" column-end="25" />
21+
<message>Syntax error : no viable alternative at input '01 ... typedef%'</message>
22+
<info severity="Error" code="27" source="Find the syntax diagram describing the statement in error in the language reference" />
23+
</diagnostic>
24+
<diagnostic file-index="2">
25+
<range line-start="6" column-start="40" line-end="6" column-end="40" />
26+
<message>Syntax error : extraneous input '.' expecting {ProgramIdentification, ProgramEnd, ClassIdentification, ClassEnd, FactoryEnd, ObjectIdentification, ObjectEnd, MethodEnd, ProcedureDivisionHeader, WorkingStorageSectionHeader, LocalStorageSectionHeader, LinkageSectionHeader, FileDescriptionEntry, DataDescriptionEntry, DataRedefinesEntry, DataRenamesEntry, DataConditionEntry, ExecStatement, FunctionDeclarationEnd, GlobalStorageSectionHeader}</message>
27+
<info severity="Error" code="27" source="Find the syntax diagram describing the statement in error in the language reference" />
28+
</diagnostic>
29+
<diagnostic file-index="2">
30+
<range line-start="1" column-start="8" line-end="1" column-end="28" />
31+
<message>Warning: "END PROGRAM" is missing.</message>
32+
<info severity="Warning" code="37" source="" />
33+
</diagnostic>
34+
</diagnostics>
35+
</build>

TypeCobol/Tools/Options-Config/TypeCobolConfiguration.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,6 @@ public class TypeCobolConfiguration : ITypeCobolCheckOptions
4141
#endif
4242
public TypeCobolCheckOption CheckEndAlignment { get; set; }
4343

44-
public bool IsErrorXML
45-
{
46-
get { return ErrorFile != null && ErrorFile.ToLower().EndsWith(".xml"); }
47-
}
4844
public List<string> Copies = new List<string>();
4945
public List<string> Dependencies = new List<string>();
5046
public bool Telemetry;

0 commit comments

Comments
 (0)