80 lines
3.0 KiB
C#
80 lines
3.0 KiB
C#
using System;
|
|
using System.Xml;
|
|
using System.Xml.Linq;
|
|
using CommandLine;
|
|
using Sprache;
|
|
using XNeedle.Parser;
|
|
using XNeedle.Parser.Elements;
|
|
using XNeedle.Transformation;
|
|
using XNeedle.Formats;
|
|
|
|
namespace XNeedle
|
|
{
|
|
class Program
|
|
{
|
|
public class Options
|
|
{
|
|
[Value(0, MetaName = "xn", Required = true, HelpText = "XN transformation definition")]
|
|
public string XnDefinition { get; set; }
|
|
|
|
[Option('i', "input", HelpText = "Input XML file", Required = true)]
|
|
public string Input { get; set; }
|
|
|
|
[Option('o', "output", HelpText = "Output XML file", Required = true)]
|
|
public string Output { get; set; }
|
|
|
|
[Option('v', "verbose", Required = false, HelpText = "Set output to verbose messages.")]
|
|
public bool Verbose { get; set; }
|
|
}
|
|
static void Main(string[] args)
|
|
{
|
|
CommandLine.Parser.Default.ParseArguments<Options>(args)
|
|
.WithParsed(RunOptions)
|
|
.WithNotParsed(HandleParseError);
|
|
}
|
|
|
|
static void RunOptions(Options opts)
|
|
{
|
|
// Auto-discover operations via reflection
|
|
BangOperation.RegisterAll();
|
|
|
|
var rawSource = File.ReadAllText(opts.XnDefinition);
|
|
var xnSource = XnParser.StripComments(rawSource);
|
|
Rule masterRule;
|
|
try
|
|
{
|
|
masterRule = (Rule)XnParser.RuleObject.Parse(xnSource);
|
|
}
|
|
catch (ParseException ex)
|
|
{
|
|
var lines = rawSource.Split('\n');
|
|
int line = ex.Position?.Line ?? -1;
|
|
int col = ex.Position?.Column ?? -1;
|
|
bool showPosition = (line != -1) && (col != -1);
|
|
|
|
if (showPosition)
|
|
{
|
|
Console.Error.WriteLine($"{opts.XnDefinition}({line},{col}): parse error: {ex.Message}");
|
|
var srcLine = line <= lines.Length ? lines[line - 1].TrimEnd() : "";
|
|
var pointer = new string(' ', Math.Max(0, col - 1)) + "^";
|
|
Console.Error.WriteLine($" {srcLine}");
|
|
Console.Error.WriteLine($" {pointer}");
|
|
}
|
|
else
|
|
{
|
|
Console.Error.WriteLine($"{opts.XnDefinition}: parse error: {ex.Message}");
|
|
}
|
|
return;
|
|
}
|
|
var doc = XDocument.Load(opts.Input, LoadOptions.PreserveWhitespace);
|
|
var encoding = XmlRoundtripWriter.DetectEncoding(File.ReadAllBytes(opts.Input));
|
|
var sloc = new SourceLocation(opts.Input, encoding);
|
|
masterRule.Transform(doc, sloc);
|
|
using var writer = XmlRoundtripWriter.Create(opts.Input, opts.Output);
|
|
doc.WriteTo(writer);
|
|
Console.WriteLine($"Applied \"{opts.XnDefinition}\" to \"{opts.Input}\" and saved result to \"{opts.Output}\"");
|
|
}
|
|
|
|
static void HandleParseError(IEnumerable<Error> errs) {}
|
|
}
|
|
} |