public static StuffObject Parse(string filename, string stuff, Func <string, string> requireResolver = null, StuffFlags flags = 0, IEnumerable <string> optionalDefines = null) { var file = new StuffFile( filename, flags.HasFlag(StuffFlags.AcceptAll) ? null : new HashSet <string>( (optionalDefines ?? StuffFile.DefaultDefines) .Select(x => x.ToUpperInvariant()))); file.Parse(stuff, flags.HasFlag(StuffFlags.Print)); var result = file.Flatten(requireResolver).ToObject(); // Workaround to avoid side-effect when StuffFlags.AcceptAll is set if (flags.HasFlag(StuffFlags.AcceptAll)) { foreach (var e in Parse(filename, stuff, requireResolver, 0, optionalDefines)) { if (!result.ContainsKey(e.Key) || result[e.Key]?.ToString().IndexOf('\n') == -1) { result[e.Key] = e.Value; } } } if (flags.HasFlag(StuffFlags.Print)) { Log.WriteLine(result.StringifyStuff()); } return(result); }
public StuffItem(StuffFile file, StuffItemType type, int line, string key, string value) { File = file; Type = type; LineNumber = line; Key = key; Value = value; }
public void Require(string filename, HashSet <string> defines, Func <string, string> requireResolver = null) { // Early out on circular include if (ContainsFile(filename)) { return; } if (requireResolver == null) { throw new NotSupportedException("'require' is not supported because a 'requireResolver' was not provided"); } var includeFile = new StuffFile(filename, defines); includeFile.Parse(requireResolver(filename)); AddFile(includeFile, requireResolver); }
public void AddFile(StuffFile file, Func <string, string> requireResolver) { AddFile(file.Filename); foreach (var item in file) { try { switch (item.Type) { case StuffItemType.Require: { var filename = item.Value.Replace('/', Path.DirectorySeparatorChar); if (filename.IsValidPath()) { filename = Path.GetFullPath(Path.Combine(file.ParentDirectory, filename)); if (File.Exists(filename)) { Require(filename, file.Defines, requireResolver); break; } } if (filename.IndexOf('*') == -1) { Log.Verbose(file.Filename.Relative() + "(" + item.LineNumber + "): File not found"); } else { foreach (var foundFile in Directory.EnumerateFiles(file.ParentDirectory, filename)) { if (!ContainsFile(foundFile)) { Require(foundFile, file.Defines, requireResolver); } } } break; } case StuffItemType.Append: { StuffItem value; if (TryGetValue(item.Key, out value)) { value.Next = item; } else { this[item.Key] = item; } break; } default: this[item.Key] = item; break; } } catch (Exception e) { throw new FormatException(file.Filename.Relative() + "(" + item.LineNumber + "): " + e.Message, e); } } }
internal Parser(StuffFile file, string stuff) { _file = file; Lexer.Tokenize(stuff, this, out _unexpectedEof); }