Ejemplo n.º 1
0
 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;
 }
Ejemplo n.º 2
0
        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;
        }
Ejemplo n.º 3
0
        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;
        }
Ejemplo n.º 4
0
 public void SetConfigFile(CLogConfigurationFile newConfig)
 {
     _sideCarFile.ConfigFile = newConfig;
 }
Ejemplo n.º 5
0
        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);
            }
        }
Ejemplo n.º 6
0
        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;
            }));
        }
Ejemplo n.º 7
0
        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;
            }));
        }
Ejemplo n.º 8
0
 public CLogFileProcessor(CLogConfigurationFile configFile)
 {
     ConfigFile = configFile;
 }
Ejemplo n.º 9
0
        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());
        }
Ejemplo n.º 10
0
        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());
        }
Ejemplo n.º 11
0
        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;
            }));
        }