public ConfigurationFileTemplateEx BuildConfigurationFileTemplate(string file, ConfigFileDefinition cf) { Regex rgIfndef = new Regex("^#ifndef ([^ ]+)"); DefineClass valuelessDefine = new DefineClass(@"#define ([^ ]+)( *)$", "#define {name}{g2: }", @"^/\* *#define ([^ ]+)( *)\*/$", "/* #define {name} */"); DefineClass defineWithValue = MakeRegularDefineClass(); Regex rgGroup = new Regex(@" */\* #+ ([^#]*) #+ \*/"); Regex rgHalModuleMacro = new Regex("HAL_(.*)MODULE_ENABLED"); PropertyList propertyList = new PropertyList { PropertyGroups = new List <PropertyGroup>() }; PropertyGroup group = null; string lastIfndef = null; List <TestableConfigurationFileParameter> testableParameters = new List <TestableConfigurationFileParameter>(); foreach (var line in File.ReadAllLines(file)) { string previousLineIfndef = lastIfndef; lastIfndef = null; Match m; bool isInverse; if (line.Trim() == "") { continue; } if ((m = rgGroup.Match(line)).Success) { if (group != null && group.Properties.Count > 0) { propertyList.PropertyGroups.Add(group); } group = new PropertyGroup { Name = m.Groups[1].Value.Trim() }; } else if ((m = rgIfndef.Match(line)).Success) { lastIfndef = m.Groups[1].Value; } else { PropertyEntry prop = null; if (valuelessDefine.IsMatch(line, out m, out isInverse)) { var macro = m.Groups[valuelessDefine.MacroNameGroup].Value; if (macro.EndsWith("HAL_CONF_H")) { continue; } valuelessDefine.FoundDefines.Add(macro); string userFriendlyName = macro; if ((m = rgHalModuleMacro.Match(macro)).Success) { string moduleName = m.Groups[1].Value; if (moduleName == "") { userFriendlyName = "Enable the HAL framework"; } else { userFriendlyName = $"Enable the {moduleName.TrimEnd('_')} module"; } } prop = new PropertyEntry.Boolean { Name = userFriendlyName, ValueForTrue = "1", ValueForFalse = "", UniqueID = macro, DefaultValue = !isInverse }; if (macro != "HAL_MODULE_ENABLED") { testableParameters.Add(new TestableConfigurationFileParameter { Name = macro, DisabledValue = "", EnabledValue = "1" }); } } else if (defineWithValue.IsMatch(line, out m, out isInverse)) { var macro = m.Groups[defineWithValue.MacroNameGroup].Value; var value = m.Groups[defineWithValue.ValueGroup].Value; var text = m.Groups[defineWithValue.CommentGroup].Value.Trim('*', '/', '!', '<', ' '); if (text == "") { text = null; } else { text = $"{text} ({macro})"; } defineWithValue.FoundDefines.Add(macro); if ((macro.StartsWith("USE_") || macro.EndsWith("_ENABLED")) && (value == "0" || value == "1" || value == "0x1")) { prop = new PropertyEntry.Boolean { Name = text ?? macro, UniqueID = macro, ValueForTrue = "1", ValueForFalse = "0", DefaultValue = value != "0" }; } else if (int.TryParse(value, out var intValue) || (value.StartsWith("0x") && int.TryParse(value.Substring(2), NumberStyles.HexNumber, null, out intValue))) { prop = new PropertyEntry.Integral { Name = text ?? macro, UniqueID = macro, DefaultValue = intValue } } ; else { prop = new PropertyEntry.String { Name = text ?? macro, UniqueID = macro, DefaultValue = value } }; } if (prop != null) { if (group == null) { throw new Exception("Property group could not be parsed. Please double-check " + file); } group.Properties.Add(prop); } } } var template = new ConfigurationFileTemplate { PropertyClasses = new[] { valuelessDefine, defineWithValue }.Select(d => d.ToPropertyClass()).ToArray(), TargetFileName = Path.GetFileName(file), PropertyList = propertyList, UserFriendlyName = "STM32 HAL Configuration", }; return(new ConfigurationFileTemplateEx(template) { TestableHeaderFiles = cf.TestableHeaderFiles, TestableParameters = testableParameters.ToArray(), }); } }
//parsing KConfig static PropertyList ParserKConfig(string pKFile) { string typ = ""; string name = "", UID = "", min = "", max = ""; bool newProperty = false, flHelp = false, flEnum = false; var def = ""; string lstHelp = ""; List <PropertyEntry> ListProperties = new List <PropertyEntry>(); PropertyEntry PropEntry = new PropertyEntry.Boolean(); bool BoolNameChoice = false; PropertyEntry.Enumerated.Suggestion SugEnum = null;// new PropertyEntry.Enumerated.Suggestion(); List <PropertyEntry.Enumerated.Suggestion> lstSugEnum = new List <PropertyEntry.Enumerated.Suggestion>(); int aCounrEnumDef = 0; int resParse; string lnHist = ""; foreach (var ln in File.ReadAllLines(pKFile)) { if (ln.Contains("menu \"Example Configuration\"")) { resParse = 3; } Match m = Regex.Match(ln, "^(menuconfig|config|choice)[ ]+([A-Z0-9_]+)"); if (m.Success) { if (flEnum) { SugEnum = new PropertyEntry.Enumerated.Suggestion(); SugEnum.InternalValue = m.Groups[2].Value; if (m.Groups[2].Value == def) { def = $"{aCounrEnumDef}"; } aCounrEnumDef++; } if (m.Groups[1].Value == "choice") { BoolNameChoice = true; flEnum = true; } if (m.Groups[1].Value == "config") { BoolNameChoice = false; } if (name != "")//save { if (typ == "string") { PropEntry = new PropertyEntry.String { Name = name, UniqueID = UID, Description = lstHelp, DefaultValue = def }; } if (typ == "int") { PropEntry = new PropertyEntry.Integral { Name = name, UniqueID = UID, Description = lstHelp, DefaultValue = Int32.TryParse(def, out resParse) ? Int32.Parse(def) : 0, MinValue = Int32.TryParse(min, out resParse) ? Int32.Parse(min) : 0, MaxValue = Int32.TryParse(max, out resParse) ? Int32.Parse(max) : 0x0FFFFFFF }; // break; } if (typ == "bool") { PropEntry = new PropertyEntry.Boolean { Name = name, UniqueID = UID, Description = lstHelp, DefaultValue = def.ToLower().Contains("y") ? true : false }; // break; } ListProperties.Add(PropEntry); if (!flEnum) { lstHelp = "";//.Clear(); } flHelp = false; } UID = m.Groups[2].Value; newProperty = true; } if (!newProperty) { continue; } if (flHelp && !ln.TrimStart().StartsWith("#") && ln.Length > 1) { lstHelp += ln.Trim(); } m = Regex.Match(ln, "^[ \t]+(int|bool|hex|prompt)[ ]+[\"]?([\\w0-9_ ]*)[\"]?"); if (m.Success) { if (flEnum) { if (m.Groups[1].Value == "bool" && !BoolNameChoice) { SugEnum.UserFriendlyName = m.Groups[2].Value; lstSugEnum.Add(SugEnum); continue; } // if (m.Groups[1].Value == "prompt") // throw new Exception(" no endchoice "+ lnHist); } typ = m.Groups[1].Value; name = m.Groups[2].Value; // if (typ == "prompt") flEnum = true; continue; } m = Regex.Match(ln, "^[ \t]+default[ \t]([\\w\\d]+)"); if (m.Success) { def = m.Groups[1].Value; continue; } m = Regex.Match(ln, "^[ \t]+range[ \t]([\\w\\d]+)[ \t]+([\\w\\d]+)"); if (m.Success) { min = m.Groups[1].Value; max = m.Groups[2].Value; continue; } if (Regex.IsMatch(ln, "^[ \t]+help[ \t]*")) { flHelp = true; continue; } if (Regex.IsMatch(ln, "^[ \t]*endchoice[ \t]*")) // end prompt { if (typ != "prompt" && typ != "bool") { throw new Exception(" no prompt in endchoice"); } flEnum = false; PropEntry = new PropertyEntry.Enumerated { Name = name, // UniqueID = UID, Description = lstHelp, DefaultEntryIndex = 1,// def.ToLower().StartsWith("y") ? true : false SuggestionList = lstSugEnum.ToArray() }; // break; ListProperties.Add(PropEntry); lstHelp = "";//.Clear(); flHelp = false; aCounrEnumDef = 0; } lnHist = ln; } // end file //save old record , need it to new function or class if (typ == "int") { PropEntry = new PropertyEntry.Integral { Name = name, UniqueID = UID, Description = lstHelp, DefaultValue = Int32.TryParse(def, out resParse) ? Int32.Parse(def) : 0, MinValue = Int32.TryParse(min, out resParse) ? Int32.Parse(min) : 0, MaxValue = Int32.TryParse(max, out resParse) ? Int32.Parse(max) : 0x0FFFFFFF }; // break; } if (typ == "bool") { PropEntry = new PropertyEntry.Boolean { Name = name, UniqueID = UID, Description = lstHelp, DefaultValue = def.ToLower().Contains("y") ? true : false }; // break; } ListProperties.Add(PropEntry); //----------------------- List <PropertyGroup> lstPrGr = new List <PropertyGroup>(); PropertyGroup PrGr = new PropertyGroup(); PrGr.Properties = ListProperties; lstPrGr.Add(PrGr); PropertyList ConfigurableProperties = new PropertyList { PropertyGroups = lstPrGr }; return(ConfigurableProperties); }
// parser type config static PropertyEntry ParserProperty(string[] pKFile, ref int countline) { string ln, TypeProperty = "none", Name = "", lstHelp = "", Macros = "", DefValue = ""; uint max = UInt32.MaxValue, resParseU; PropertyEntry PropEntry = null; int resParse, min = -1; bool flHelp = false; bool typNoName = false; while (countline < pKFile.Count()) { ln = pKFile[countline]; if (ln.StartsWith("#")) { countline++; continue; } if (!ln.StartsWith("config") && !ln.StartsWith("menuconfig") && Macros == "") { return(null); } if (ln.StartsWith("end") || ln.StartsWith("source") || ln.StartsWith("menu ")) { if (Macros != "")//заполнены поля { countline--; break; } else { return(null); } } Match m = Regex.Match(ln, "^(menuconfig|config|choice)[ ]+([A-Z0-9_]+)"); if (m.Success) { if (TypeProperty != "none")//parsing is done { countline--; break; } if (m.Groups[1].Value != "config" && m.Groups[1].Value != "menuconfig") { countline--; return(null); } Macros = strPrefixConfProperty + m.Groups[2].Value; } if (flHelp) { lstHelp += ln; } else { m = Regex.Match(ln, "^[ \t]+(int|bool|hex|string)[ ]*[\"]?(['\\w0-9_ \\(\\)-]*)[\"]?"); if (m.Success) { TypeProperty = m.Groups[1].Value; if (m.Groups[2].Value == "") { countNoNameProp++; Console.WriteLine(ln); if (false) { Name = Macros; typNoName = true; } else { if (Macros == "ESP32_PHY_MAX_TX_POWER" || Macros == "PHY_ENABLED") { Name = Macros; } else { TypeProperty = "none"; countline++; continue; } // no dublecate } } else { Name = m.Groups[2].Value; } //TypeProperty = m.Groups[1].Value; } else { if (!typNoName) { m = Regex.Match(ln, "^[ \t]+default[\t ]+(['/\"_\\w 0-9-]*)"); if (m.Success) { DefValue = m.Groups[1].Value; } } else { if (ln.Contains("default")) { // flHelp = true; Console.WriteLine(ln); } } m = Regex.Match(ln, "^[ \t]+range[ \t]([\\w\\d]+)[ \t]+([\\w\\d]+)"); if (m.Success) { var minInt = Int32.TryParse(m.Groups[1].Value, out resParse) ? Int32.Parse(m.Groups[1].Value) : 0; var maxInt = UInt32.TryParse(m.Groups[2].Value, out resParseU) ? UInt32.Parse(m.Groups[2].Value) : UInt32.MaxValue; min = ((min < minInt) && (min > -1)) ? min : minInt; max = maxInt; } if (Regex.IsMatch(ln, "^[ \t]+help[ \t]*")) { flHelp = true; } } } countline++; } // save switch (TypeProperty) { case "string": PropEntry = new PropertyEntry.String() { Name = Name, UniqueID = Macros, Description = lstHelp, DefaultValue = DefValue }; break; case "bool": PropEntry = new PropertyEntry.Boolean() { Name = Name, UniqueID = Macros, Description = lstHelp, DefaultValue = DefValue.ToLower().Contains("y") ? true : false }; break; case "int": case "hex": PropEntry = new PropertyEntry.Integral() { Name = Name, UniqueID = Macros, Description = lstHelp, DefaultValue = Int32.TryParse(DefValue, out resParse) ? Int32.Parse(DefValue) : 0, MinValue = (min == -1) ? 0 : min, MaxValue = (min == -1) ? Int32.MaxValue : (int)max }; break; case "none": return(null); default: throw new Exception(" unknow type config"); } return(PropEntry); }