public CLogDecodedTraceLine(string uniqueId, string sourceFile, string userString, string userStringNoPrefix, CLogLineMatch m, CLogConfigurationFile c, string mac, CLogFileProcessor.CLogVariableBundle[] args) { SourceFile = sourceFile; macroName = mac; UniqueId = uniqueId; match = m; configFile = c; TraceString = userString; splitArgs = args; TraceStringNoPrefix = userStringNoPrefix; }
public CLogDecodedTraceLine(string uniqueId, string sourceFile, string userString, string userStringNoPrefix, CLogLineMatch m, CLogConfigurationFile c, CLogTraceMacroDefination mac, CLogFileProcessor.CLogVariableBundle[] args, CLogFileProcessor.DecomposedString decompString) { SourceFile = sourceFile; macro = mac; UniqueId = uniqueId; match = m; configFile = c; TraceString = userString; splitArgs = args; TraceStringNoPrefix = userStringNoPrefix; DecomposedString = decompString; }
public void UpdateConfigFile(CLogConfigurationFile newConfigFile) { // Ideally, we'd use CLogConfigurationFile.AreWeDirty, but because of the tricks // we do around serialization, we can't without a major refactor if (newConfigFile == null || ConfigFile == null) { AreDirty = true; ConfigFile = newConfigFile; return; } // Serialize old config bool old = ConfigFile.SerializeChainedConfigurations; ConfigFile.SerializeChainedConfigurations = true; string serializedOldConfig = JsonConvert.SerializeObject(ConfigFile); ConfigFile.SerializeChainedConfigurations = old; // Serialize new config old = newConfigFile.SerializeChainedConfigurations; newConfigFile.SerializeChainedConfigurations = true; string serializedNewConfig = JsonConvert.SerializeObject(newConfigFile); newConfigFile.SerializeChainedConfigurations = old; if (serializedOldConfig != serializedNewConfig) { AreDirty = true; ChangesList.Add("Configuration file or dependencies changed"); } ConfigFile = newConfigFile; }
public void SetConfigFile(CLogConfigurationFile newConfig) { _sideCarFile.ConfigFile = newConfig; }
public static void DecodeAndTraceToConsole(StreamWriter outputfile, CLogDecodedTraceLine bundle, string errorLine, CLogConfigurationFile config, Dictionary <string, IClogEventArg> valueBag, EventInformation eventInfo, bool showTimeStamp, bool showCPUInfo) { try { if (null == bundle) { Console.WriteLine($"Invalid TraceLine : {errorLine}"); return; } StringBuilder toPrint = new StringBuilder(); if (null != eventInfo) { if (showCPUInfo) { if (!String.IsNullOrEmpty(eventInfo.CPUId)) { toPrint.Append("[" + eventInfo.CPUId + "]"); } toPrint.Append("["); bool havePid = false; if (!String.IsNullOrEmpty(eventInfo.ProcessId)) { toPrint.Append(eventInfo.ProcessId); havePid = true; } if (!String.IsNullOrEmpty(eventInfo.ThreadId)) { if (havePid) { toPrint.Append("."); } toPrint.Append(eventInfo.ThreadId); } toPrint.Append("]"); } if (showTimeStamp) { toPrint.Append("[" + eventInfo.Timestamp.ToString("hh:mm:ss.ffffff") + "]"); } } string clean; CLogFileProcessor.CLogTypeContainer[] types = CLogFileProcessor.BuildTypes(config, null, bundle.TraceString, null, out clean); if (0 == types.Length) { toPrint.Append(bundle.TraceString); goto toPrint; } CLogFileProcessor.CLogTypeContainer first = types[0]; if (valueBag.Count > 0) { int argIndex = 0; foreach (CLogFileProcessor.CLogTypeContainer type in types) { var arg = bundle.splitArgs[argIndex]; if (0 != arg.DefinationEncoding.CompareTo(type.TypeNode.DefinationEncoding)) { Console.WriteLine("Invalid Types in Traceline"); throw new Exception("InvalidType : " + arg.DefinationEncoding); } CLogEncodingCLogTypeSearch payload = type.TypeNode; if (!valueBag.TryGetValue(arg.MacroVariableName, out IClogEventArg value)) { toPrint.Append($"<SKIPPED:BUG:MISSINGARG:{arg.MacroVariableName}:{payload.EncodingType}>"); } else { if (string.IsNullOrEmpty(type.TypeNode.CustomDecoder)) { toPrint.Append($"{type.LeadingString}{value.AsString}"); } else { string decodedValue; config.DecodeUsingCustomDecoder(type.TypeNode, value, bundle.match, out decodedValue); toPrint.Append($"{type.LeadingString}{decodedValue}"); } } first = type; ++argIndex; } string tail = bundle.TraceString.Substring(types[types.Length - 1].ArgStartingIndex + types[types.Length - 1].ArgLength); toPrint.Append(tail); } else { toPrint.Clear(); toPrint.Append(bundle.TraceString); } toPrint: if (null == outputfile) { Console.WriteLine(toPrint); } else { outputfile.WriteLine(toPrint); } } catch (Exception e) { Console.WriteLine($"Invalid TraceLine : {errorLine} " + e); } }
private static int Main(string[] args) { ParserResult <CommandLineArguments> o = Parser.Default.ParseArguments <CommandLineArguments>(args); return(o.MapResult( options => { try { // // The CommandLineArguments library validates most input arguments for us, there are few ones that are complicated // this secondary check looks for those and errors out if present // if (!options.IsValid()) { CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Invalid args"); return -1; } CLogConfigurationFile configFile = CLogConfigurationFile.FromFile(options.ConfigurationFile); configFile.ProfileName = options.ConfigurationProfile; CLogSidecar sidecar; if (!Directory.Exists(Path.GetDirectoryName(options.SidecarFile))) { Directory.CreateDirectory(Path.GetDirectoryName(options.SidecarFile)); } if (!File.Exists(options.SidecarFile)) { sidecar = new CLogSidecar(); } else { string json = File.ReadAllText(options.SidecarFile); sidecar = CLogSidecar.FromJson(json); if (null == sidecar) { sidecar = new CLogSidecar(); } } sidecar.SetConfigFile(configFile); string outputCFile = Path.Combine(Path.GetDirectoryName(options.OutputFile), options.ScopePrefix + "_" + Path.GetFileName(options.OutputFile)) + ".c"; configFile.ScopePrefix = options.ScopePrefix; configFile.FilePath = Path.GetFullPath(options.ConfigurationFile); configFile.OverwriteHashCollisions = options.OverwriteHashCollisions; CLogTraceMacroDefination syslog = new CLogTraceMacroDefination(); syslog.EncodedArgNumber = 1; syslog.MacroName = "syslog"; syslog.MacroConfiguration = new System.Collections.Generic.Dictionary <string, string>(); syslog.MacroConfiguration[options.ConfigurationProfile] = options.ConfigurationProfile; configFile.SourceCodeMacros.Add(syslog); CLogFileProcessor processor = new CLogFileProcessor(configFile); SysLogToClog converter = new SysLogToClog(); string content = File.ReadAllText(options.InputFile); string output = processor.ConvertFile(configFile, null, converter, content, options.InputFile, true); if (!Directory.Exists(Path.GetDirectoryName(options.OutputFile))) { Directory.CreateDirectory(Path.GetDirectoryName(options.OutputFile)); } File.WriteAllText(options.InputFile, output); } catch (CLogHandledException e) { e.PrintDiagnostics(); return -2; } return 0; }, err => { Console.WriteLine("Bad Args : " + err); return -1; })); }
private static int Main(string[] args) { // Manually parse installDirectory, as it interferes with the required configFile // The argument still shows up in CommandLineArguments to be shown in help. for (int i = 0; i < args.Length; i++) { if (args[i] == "--installDirectory") { if (i + 1 == args.Length) { CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Must pass an argument to --installDirectory"); return(-1); } return(PerformInstall(args[i + 1])); } } ParserResult <CommandLineArguments> o = Parser.Default.ParseArguments <CommandLineArguments>(args); return(o.MapResult( options => { try { // // The CommandLineArguments library validates most input arguments for us, there are few ones that are complicated // this secondary check looks for those and errors out if present // if (!options.IsValid()) { CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Invalid args"); return -1; } if (!string.IsNullOrWhiteSpace(options.InstallDependencies)) { CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Internal error, this should have been handled at a previous step"); return -1; } CLogConfigurationFile configFile = CLogConfigurationFile.FromFile(options.ConfigurationFile); configFile.ProfileName = options.ConfigurationProfile; if (options.ReadOnly && !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("CLOG_FORCE_WRITABLE"))) { options.ReadOnly = false; CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Wrn, "WARNING: CLOG was instructed via --readOnly not to emit changes however this was overridden with CLOG_FORCE_WRITABLE environment variable"); } if (options.OverwriteHashCollisions || !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("CLOG_OVERWRITE_COLLISIONS"))) { options.OverwriteHashCollisions = true; options.ReadOnly = false; CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, ""); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, ""); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, ""); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "***********************************************"); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, ""); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Overwriting of sidecare collisions is set by environment variable CLOG_OVERWRITE_COLLISIONS. This setting is only to be used while making large refactors and should not be included in build environments or standard development environments"); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, ""); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "***********************************************"); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, ""); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, ""); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, ""); } if (options.Devmode || !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("CLOG_DEVELOPMENT_MODE"))) { options.ReadOnly = false; options.OverwriteHashCollisions = true; configFile.DeveloperMode = true; CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Wrn, "WARNING: CLOG was instructed to enter a developer mode"); } if (options.LintConfig) { if (!configFile.MarkPhase) { CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Lint operation only works on config files placed into the 'MarkPhase'. This can be a destricutive action, please read the docs for more information"); return -10; } configFile.Lint(); configFile.Save(false); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, "Lint operation complete"); return 0; } if (options.UpgradeConfigFile) { configFile.UpdateVersion(); configFile.Save(false); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, "Config upgrade complete"); return 0; } CLogSidecar sidecar; if (!Directory.Exists(Path.GetDirectoryName(options.SidecarFile))) { Directory.CreateDirectory(Path.GetDirectoryName(options.SidecarFile)); } if (!File.Exists(options.SidecarFile)) { sidecar = new CLogSidecar(); } else { string json = File.ReadAllText(options.SidecarFile); sidecar = CLogSidecar.FromJson(json); if (null == sidecar) { sidecar = new CLogSidecar(); } } // Check for outdated config file sidecar.UpdateConfigFile(configFile); if (options.RefreshCustomTypeProcessor) { configFile.ForceDecoderCompile(); sidecar.Save(options.SidecarFile); return 0; } string outputCFile = Path.Combine(Path.GetDirectoryName(options.OutputFile), options.ScopePrefix + "_" + Path.GetFileName(options.OutputFile)) + ".c"; configFile.ScopePrefix = options.ScopePrefix; configFile.FilePath = Path.GetFullPath(options.ConfigurationFile); configFile.OverwriteHashCollisions = options.OverwriteHashCollisions; //Delete the output file; we want to encourage build breaks if something goes wrong if (File.Exists(options.OutputFile)) { File.Delete(options.OutputFile); } if (File.Exists(outputCFile)) { File.Delete(outputCFile); } CLogFileProcessor processor = new CLogFileProcessor(configFile); CLogFullyDecodedMacroEmitter fullyDecodedMacroEmitter = new CLogFullyDecodedMacroEmitter(options.InputFile, sidecar); fullyDecodedMacroEmitter.AddClogModule(sidecar); CLogTraceLoggingOutputModule traceLoggingEmitter = new CLogTraceLoggingOutputModule(); fullyDecodedMacroEmitter.AddClogModule(traceLoggingEmitter); CLogDTraceOutputModule dtrace = new CLogDTraceOutputModule(); fullyDecodedMacroEmitter.AddClogModule(dtrace); CLogSystemTapModule systemTap = new CLogSystemTapModule(); fullyDecodedMacroEmitter.AddClogModule(systemTap); CLogSysLogModule syslog = new CLogSysLogModule(); fullyDecodedMacroEmitter.AddClogModule(syslog); CLogSTDOUT stdout = new CLogSTDOUT(); fullyDecodedMacroEmitter.AddClogModule(stdout); CLogManifestedETWOutputModule manifestedEtwOutput = new CLogManifestedETWOutputModule(options.ReadOnly); fullyDecodedMacroEmitter.AddClogModule(manifestedEtwOutput); CLogLTTNGOutputModule lttngOutput = new CLogLTTNGOutputModule(options.InputFile, options.OutputFile, options.OutputFile + ".lttng.h", options.DynamicTracepointProvider); fullyDecodedMacroEmitter.AddClogModule(lttngOutput); if (!File.Exists(options.InputFile)) { CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, $"Invalid Input File : {Path.GetFileName(options.InputFile)}"); throw new CLogEnterReadOnlyModeException("InvalidInputFile", CLogHandledException.ExceptionType.InvalidInputFile, null); } string content = File.ReadAllText(options.InputFile); string output = processor.ConvertFile(configFile, fullyDecodedMacroEmitter, content, options.InputFile, false); if (!content.Contains(Path.GetFileName(options.OutputFile))) { CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, $"You must #include the clog output file {Path.GetFileName(options.OutputFile)}"); throw new CLogEnterReadOnlyModeException("MustIncludeCLogHeader", CLogHandledException.ExceptionType.SourceMustIncludeCLOGHeader, null); } fullyDecodedMacroEmitter.FinishedProcessing(); StringBuilder clogFile = new StringBuilder(); clogFile.AppendLine("#include <clog.h>"); clogFile.Append(fullyDecodedMacroEmitter.HeaderInit); foreach (var macro in processor.MacrosInUse) { clogFile.AppendLine($"#ifndef _clog_MACRO_{macro.MacroName}"); clogFile.AppendLine($"#define _clog_MACRO_{macro.MacroName} 1"); clogFile.AppendLine( $"#define {macro.MacroName}(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))"); clogFile.AppendLine("#endif"); } clogFile.AppendLine("#ifdef __cplusplus"); clogFile.AppendLine("extern \"C\" {"); clogFile.AppendLine("#endif"); clogFile.Append(fullyDecodedMacroEmitter.HeaderFile); clogFile.AppendLine("#ifdef __cplusplus"); clogFile.AppendLine("}"); clogFile.AppendLine("#endif"); clogFile.AppendLine("#ifdef CLOG_INLINE_IMPLEMENTATION"); clogFile.AppendLine("#include \"" + Path.GetFileName(outputCFile) + "\""); clogFile.AppendLine("#endif"); if (!Directory.Exists(Path.GetDirectoryName(options.OutputFile))) { Console.WriteLine("Creating Directory for Output : " + Path.GetDirectoryName(options.OutputFile)); Directory.CreateDirectory(Path.GetDirectoryName(options.OutputFile)); } if (sidecar.AreDirty || configFile.AreWeDirty()) { if (options.ReadOnly) { if (sidecar.AreDirty) { Console.WriteLine("Sidecar is dirty"); } if (configFile.AreWeDirty()) { Console.WriteLine("ConfigFile is dirty"); } sidecar.PrintDirtyReasons(); throw new CLogEnterReadOnlyModeException("WontWriteWhileInReadonlyMode:SideCar", CLogHandledException.ExceptionType.WontWriteInReadOnlyMode, null); } configFile.ForceDecoderCompile(); sidecar.Save(options.SidecarFile); } if (configFile.AreWeDirty() || configFile.AreWeInMarkPhase()) { if (options.ReadOnly) { throw new CLogEnterReadOnlyModeException("WontWriteWhileInReadonlyMode:ConfigFile", CLogHandledException.ExceptionType.WontWriteInReadOnlyMode, null); } Console.WriteLine("Configuration file was updated, saving..."); Console.WriteLine($" {configFile.FilePath}"); configFile.Save(false); } File.WriteAllText(options.OutputFile, clogFile.ToString()); File.WriteAllText(outputCFile, fullyDecodedMacroEmitter.SourceFile); } catch (CLogHandledException e) { e.PrintDiagnostics(); return -2; } return 0; }, err => { Console.WriteLine("Bad Args : " + err); return -1; })); }
public CLogFileProcessor(CLogConfigurationFile configFile) { ConfigFile = configFile; }
public static CLogTypeContainer[] BuildTypes(CLogConfigurationFile configFile, CLogLineMatch traceLineMatch, string argString, string traceLine, out string cleanedString) { List <CLogTypeContainer> ret = new List <CLogTypeContainer>(); string pieces = string.Empty; int argCount = 0; cleanedString = string.Empty; string prefixString = ""; if (string.IsNullOrEmpty(argString)) { return(new CLogTypeContainer[0]); } // Make surew e start and stop with a quote - this prevents L"" (unicode) as well as other oddities that seem to be 'okay' in WPP but shoudlnt be okay argString = argString.Trim(); for (int i = 0; i < argString.Length; ++i) { pieces += argString[i]; if ('%' == argString[i]) { pieces += argCount++; pieces += " "; CLogTypeContainer newNode = new CLogTypeContainer(); newNode.LeadingString = prefixString; newNode.ArgStartingIndex = i; ++i; CLogEncodingCLogTypeSearch t; try { // 'i' will point to the final character on a match (such that i+1 is the next fresh character) t = configFile.FindTypeAndAdvance(argString, traceLineMatch, ref i); } catch (CLogTypeNotFoundException e) { throw e; } newNode.TypeNode = t; newNode.ArgLength = i - newNode.ArgStartingIndex + 1; prefixString = ""; ret.Add(newNode); } else { prefixString += argString[i]; } } cleanedString = pieces; return(ret.ToArray()); }
public static CLogTypeContainer[] BuildTypes(CLogConfigurationFile configFile, CLogLineMatch traceLineMatch, string argString, string traceLine, out DecomposedString decompString) { List <CLogTypeContainer> ret = new List <CLogTypeContainer>(); string pieces = string.Empty; int argCount = 0; decompString = new DecomposedString(); string prefixString = ""; DecomposedString.EncodingArg currentArg = decompString.CreateNewArg(); if (string.IsNullOrEmpty(argString)) { return(new CLogTypeContainer[0]); } // Make sure we start and stop with a quote - this prevents L"" (unicode) as well as other oddities that seem to be 'okay' in WPP but shoudlnt be okay argString = argString.Trim(); for (int i = 0; i < argString.Length; ++i) { pieces += argString[i]; currentArg.Prefix += argString[i]; if ('%' == argString[i]) { pieces += (argCount++) + 1;; CLogTypeContainer newNode = new CLogTypeContainer(); newNode.LeadingString = prefixString; newNode.ArgStartingIndex = i; currentArg = decompString.CreateNewArg(); ++i; // Check to see if a custom name is specified for this type string preferredName = ""; if ('{' == argString[i]) { // Skip the opening brace i++; if (i == argString.Length) { throw new CLogEnterReadOnlyModeException("InvalidNameFormatInTypeSpcifier", CLogHandledException.ExceptionType.TooFewArguments, traceLineMatch); } while (',' != argString[i]) { // If we find a closing brace or a space before finding the comma, it's a parsing error if ('}' == argString[i] || char.IsWhiteSpace(argString[i])) { throw new CLogEnterReadOnlyModeException("InvalidNameFormatInTypeSpcifier", CLogHandledException.ExceptionType.WhiteSpaceNotAllowed, traceLineMatch); } preferredName += argString[i]; i++; if (i == argString.Length) { throw new CLogEnterReadOnlyModeException("InvalidNameFormatInTypeSpcifier", CLogHandledException.ExceptionType.TooFewArguments, traceLineMatch); } } // Skip the comma i++; // Don't allow white spaces after comma if (char.IsWhiteSpace(argString[i])) { throw new CLogEnterReadOnlyModeException("InvalidNameFormatInTypeSpcifier", CLogHandledException.ExceptionType.WhiteSpaceNotAllowed, traceLineMatch); } if (i == argString.Length) { throw new CLogEnterReadOnlyModeException("InvalidNameFormatInTypeSpcifier", CLogHandledException.ExceptionType.TooFewArguments, traceLineMatch); } } CLogEncodingCLogTypeSearch t; try { // 'i' will point to the final character on a match (such that i+1 is the next fresh character) t = configFile.FindTypeAndAdvance(argString, traceLineMatch, ref i); } catch (CLogTypeNotFoundException) { throw; } // If we found a preferred name, the next character after the type should be a closing brace if (preferredName.Length != 0) { i++; if (i == argString.Length || '}' != argString[i]) { throw new CLogEnterReadOnlyModeException("InvalidNameFormatInTypeSpcifier", CLogHandledException.ExceptionType.TooFewArguments, traceLineMatch); } newNode.PreferredName = preferredName; } // Compute lengths newNode.TypeNode = t; newNode.ArgLength = i - newNode.ArgStartingIndex + 1; currentArg.Type = t; prefixString = ""; ret.Add(newNode); } else { prefixString += argString[i]; } } if (!pieces.Equals(decompString.AsManifestedETWEncoding)) { throw new Exception("ETW strings dont match"); } return(ret.ToArray()); }
private static int Main(string[] args) { ParserResult <CommandLineArguments> o = Parser.Default.ParseArguments <CommandLineArguments>(args); return(o.MapResult( options => { string currentFile = null; try { // // The CommandLineArguments library validates most input arguments for us, there are few ones that are complicated // this secondary check looks for those and errors out if present // if (!options.IsValid()) { CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Invalid args"); return -1; } CLogConfigurationFile configFile = CLogConfigurationFile.FromFile(options.ConfigurationFile); configFile.ProfileName = options.ConfigurationProfile; if (options.ReadOnly && !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("CLOG_FORCE_WRITABLE"))) { options.ReadOnly = false; CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Wrn, "WARNING: CLOG was instructed via --readOnly not to emit changes however this was overridden with CLOG_FORCE_WRITABLE environment variable"); } if (options.OverwriteHashCollisions || !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("CLOG_OVERWRITE_COLLISIONS"))) { options.OverwriteHashCollisions = true; options.ReadOnly = false; CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, ""); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, ""); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, ""); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "***********************************************"); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, ""); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Overwriting of sidecare collisions is set by environment variable CLOG_OVERWRITE_COLLISIONS. This setting is only to be used while making large refactors and should not be included in build environments or standard development environments"); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, ""); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "***********************************************"); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, ""); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, ""); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, ""); } if (options.Devmode || !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("CLOG_DEVELOPMENT_MODE"))) { options.ReadOnly = false; options.OverwriteHashCollisions = true; configFile.DeveloperMode = true; CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Wrn, "WARNING: CLOG was instructed to enter a developer mode"); } if (options.LintConfig) { if (!configFile.MarkPhase) { CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, "Lint operation only works on config files placed into the 'MarkPhase'. This can be a destricutive action, please read the docs for more information"); return -10; } configFile.Lint(); configFile.Save(false); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, "Lint operation complete"); return 0; } if (options.UpgradeConfigFile) { configFile.UpdateVersion(); configFile.Save(false); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, "Config upgrade complete"); return 0; } CLogSidecar sidecar; if (!Directory.Exists(Path.GetDirectoryName(options.SidecarFile))) { Directory.CreateDirectory(Path.GetDirectoryName(options.SidecarFile)); } if (!File.Exists(options.SidecarFile)) { sidecar = new CLogSidecar(); } else { string json = File.ReadAllText(options.SidecarFile); sidecar = CLogSidecar.FromJson(json); if (null == sidecar) { sidecar = new CLogSidecar(); } } sidecar.SetConfigFile(configFile); if (options.RefreshCustomTypeProcessor) { configFile.ForceDecoderCompile(); sidecar.Save(options.SidecarFile); return 0; } // // BUGBUG: refactoring needed for handling batches of input files, expecially // now that managed languages are coming along. Leaving this unaddressed // for now while the best way is still elusive // List <ICLogBatchingModule> batchingModules = new List <ICLogBatchingModule>(); Console.WriteLine("Number of files : " + (new List <string>(options.InputFiles)).Count); foreach (string inputFile in options.InputFiles) { Console.WriteLine("Processing: " + inputFile); currentFile = inputFile; string outputFile = options.GetOutputFileName(inputFile); string outputCFile = Path.Combine(Path.GetDirectoryName(outputFile), options.ScopePrefix + "_" + Path.GetFileName(outputFile)) + ".c"; configFile.ScopePrefix = options.ScopePrefix; configFile.FilePath = Path.GetFullPath(options.ConfigurationFile); configFile.OverwriteHashCollisions = options.OverwriteHashCollisions; //Delete the output file; we want to encourage build breaks if something goes wrong if (File.Exists(outputFile)) { File.Delete(outputFile); } if (File.Exists(outputCFile)) { File.Delete(outputCFile); } CLogFileProcessor processor = new CLogFileProcessor(configFile); CLogFullyDecodedMacroEmitter fullyDecodedMacroEmitter = new CLogFullyDecodedMacroEmitter(inputFile, sidecar); fullyDecodedMacroEmitter.AddClogModule(sidecar); CLogTraceLoggingOutputModule traceLoggingEmitter = new CLogTraceLoggingOutputModule(); fullyDecodedMacroEmitter.AddClogModule(traceLoggingEmitter); CLogDTraceOutputModule dtrace = new CLogDTraceOutputModule(); fullyDecodedMacroEmitter.AddClogModule(dtrace); CLogSysLogModule syslog = new CLogSysLogModule(); fullyDecodedMacroEmitter.AddClogModule(syslog); CLogSTDOUT stdout = new CLogSTDOUT(); fullyDecodedMacroEmitter.AddClogModule(stdout); CLogManifestedETWOutputModule manifestedEtwOutput = new CLogManifestedETWOutputModule(options.ReadOnly); fullyDecodedMacroEmitter.AddClogModule(manifestedEtwOutput); CLogLTTNGOutputModule lttngOutput = new CLogLTTNGOutputModule(inputFile, outputFile, outputFile + ".lttng.h", options.DynamicTracepointProvider); fullyDecodedMacroEmitter.AddClogModule(lttngOutput); if (!File.Exists(inputFile)) { CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, $"Invalid Input File (file doesnt exist) : {inputFile}"); throw new CLogEnterReadOnlyModeException("InvalidInputFile", CLogHandledException.ExceptionType.InvalidInputFile, null); } CLogOutputInfo outputInfo = new CLogOutputInfo(); outputInfo.OutputDirectory = options.OutputDirectory; outputInfo.OutputFileName = outputFile; outputInfo.InputFileName = inputFile; string content = File.ReadAllText(inputFile); string output = processor.ConvertFile(configFile, outputInfo, fullyDecodedMacroEmitter, content, inputFile, false); // TODO: BUGBUG - Java won't ever do this //if (!content.Contains(Path.GetFileName(outputFile))) //{ // CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Std, $"You must #include the clog output file {Path.GetFileName(outputFile)}"); // throw new CLogEnterReadOnlyModeException("MustIncludeCLogHeader", CLogHandledException.ExceptionType.SourceMustIncludeCLOGHeader, null); //} fullyDecodedMacroEmitter.FinishedProcessing(outputInfo); StringBuilder clogFile = new StringBuilder(); clogFile.AppendLine($"#ifndef CLOG_DO_NOT_INCLUDE_HEADER"); clogFile.AppendLine("#include <clog.h>"); clogFile.AppendLine($"#endif"); clogFile.Append(fullyDecodedMacroEmitter.HeaderInit); foreach (var macro in processor.MacrosInUse) { clogFile.AppendLine($"#ifndef _clog_MACRO_{macro.MacroName}"); clogFile.AppendLine($"#define _clog_MACRO_{macro.MacroName} 1"); clogFile.AppendLine( $"#define {macro.MacroName}(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))"); clogFile.AppendLine("#endif"); } clogFile.AppendLine("#ifdef __cplusplus"); clogFile.AppendLine("extern \"C\" {"); clogFile.AppendLine("#endif"); clogFile.Append(fullyDecodedMacroEmitter.HeaderFile); clogFile.AppendLine("#ifdef __cplusplus"); clogFile.AppendLine("}"); clogFile.AppendLine("#endif"); clogFile.AppendLine("#ifdef CLOG_INLINE_IMPLEMENTATION"); clogFile.AppendLine("#include \"" + Path.GetFileName(outputCFile) + "\""); clogFile.AppendLine("#endif"); // // BUGBUG : the intent in saving needs to be // 1. delete any output files early - before we start, getting us into a safe state (build breaks) // 2. save sidecars and other items that make assumptions about the emitted code // 3. save emitted code // // the goal of these orderings is to be safe in the event of failure/crash // if (!Directory.Exists(Path.GetDirectoryName(outputFile))) { Console.WriteLine("Creating Directory for Output : " + Path.GetDirectoryName(outputFile)); Directory.CreateDirectory(Path.GetDirectoryName(outputFile)); } if (sidecar.AreDirty || configFile.AreWeDirty()) { if (options.ReadOnly) { if (sidecar.AreDirty) { Console.WriteLine("Sidecar is dirty"); } if (configFile.AreWeDirty()) { Console.WriteLine("ConfigFile is dirty"); } sidecar.PrintDirtyReasons(); throw new CLogEnterReadOnlyModeException("WontWriteWhileInReadonlyMode:SideCar", CLogHandledException.ExceptionType.WontWriteInReadOnlyMode, null); } configFile.ForceDecoderCompile(); sidecar.Save(options.SidecarFile); } if (configFile.AreWeDirty() || configFile.AreWeInMarkPhase()) { if (options.ReadOnly) { throw new CLogEnterReadOnlyModeException("WontWriteWhileInReadonlyMode:ConfigFile", CLogHandledException.ExceptionType.WontWriteInReadOnlyMode, null); } Console.WriteLine("Configuration file was updated, saving..."); Console.WriteLine($" {configFile.FilePath}"); configFile.Save(false); } File.WriteAllText(outputFile, clogFile.ToString()); File.WriteAllText(outputCFile, fullyDecodedMacroEmitter.SourceFile); } currentFile = null; // // Enumerate batching modules, allowing them to save // foreach (var m in batchingModules) { CLogOutputInfo outputInfo = new CLogOutputInfo(); outputInfo.OutputDirectory = options.OutputDirectory; m.FinishedBatch(outputInfo); } } catch (CLogHandledException e) { if (null != currentFile) { CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"Failure in file : {currentFile}"); } e.PrintDiagnostics(options.VerboseErrors); return -2; } catch (Exception e) { CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"---------------------------------------------------------------------------"); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"CLOG has crashed processing : {currentFile}."); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $" if you're reading this, we consider seeing this message a bug. Even if the message"); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $" you're about to read is sufficient to diagnose, we'd like to improve the user experience"); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $" please consider filing a bug, with repro files and --verboseErrors"); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $""); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $""); CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, $"Exception:"); if (!options.VerboseErrors) { CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, " " + e.Message); return -1; } else { CLogConsoleTrace.TraceLine(CLogConsoleTrace.TraceType.Err, e.ToString()); } } return 0; }, err => { Console.WriteLine("Bad Args : " + err); return -1; })); }