/// <summary> /// Laad het bestand uit de reader in. Noteer voor functies in welk bestand ze zaten. /// Let op niet nog een keer hetzelfde bestand te gaan laden. Voor je het weet zit je in een loop. /// En een loop mag niet. /// Een includefile mag geen code opleveren. Alleen: lege regels, regels met commentaar, en regels met alleen een enkele '@' /// </summary> /// <param name="filename">Naam van de file die we nu doen</param> /// <param name="reader">De textlezer</param> /// <param name="loadedfiles">Lijst files die we al gehad hebben, inclusief de 'filename'</param> /// <param name="functioninfo">Lijst te vullen functies</param> /// <param name="includefile">Als deze true is gaat het om een includefile</param> /// <param name="conceptname">Als geen includefile, dan is conceptname gevuld met de naam van het type waarvoor gegenereerd is. /// De file zelf kan hergebruikt worden in principe meerdere concepten, mits ze gelijke gegevens gebruiken natuurlijk</param> /// <returns>De programmacode die niet in functies zat, elke regel voorafgegaan door het regelnummer</returns> private StringCollection LoadSourceFromReader(String filename, TextReader reader, StringCollection loadedfiles, Hashtable functioninfo, bool includefile, string conceptname) { StringCollection sc = new StringCollection(); int linenr = 1; //linenr update string s = reader.ReadLine(); while (s != null) { if (s.TrimStart().StartsWith("@")) { string sLineTrim = s.TrimStart().Substring(1).TrimStart(); if (sLineTrim.StartsWith("Function ")) { SourceCodeContext fncontext = new SourceCodeContext(conceptname, filename, linenr++); FunctionInfo fi = new FunctionInfo(fncontext, s); s = reader.ReadLine(); while (s != null) // of bij EndFunction eruit gebroken... { sLineTrim = s.TrimStart(); if (sLineTrim.StartsWith("@")) { sLineTrim = sLineTrim.Substring(1).TrimStart() + " "; if (sLineTrim.StartsWith("EndFunction ")) { linenr++; break; } } fi.Add(linenr++.ToString() + ":" + s); s = reader.ReadLine(); } if (s == null) { throw new EndFunctionMissingException(fncontext, fi.Name); } if (functioninfo.Contains(fi.Name)) { FunctionInfo otherone = functioninfo[fi.Name] as FunctionInfo; throw new DuplicateFunctionDefinitionException(fncontext, fi.Name, otherone.DeclaredAt); } functioninfo.Add(fi.Name, fi); s = reader.ReadLine(); continue; } if (sLineTrim.StartsWith("Include ")) { // Verzamel eerst de handel in het aangegeven bestand. // Merge de resultaten met de functioninfo van 'ons'.(check dat er geen dubbele functies in zitten. // En ga verder met de rest. String includefilename = sLineTrim.Substring(8).Trim(); if (loadedfiles.Contains(includefilename)) { throw new IncludeFileLoopException(new SourceCodeContext(conceptname, filename, linenr), includefilename); } String includefilepath = TemplateUtil.Instance().CombineAndCompact(Path.GetDirectoryName(filename), includefilename); if (!File.Exists(includefilepath)) { throw new IncludeFileNotFoundException(new SourceCodeContext(conceptname, filename, linenr), includefilepath); } TextReader r = new StreamReader(includefilepath); loadedfiles.Add(includefilename); StringCollection files = new StringCollection(); foreach (string s1 in loadedfiles) { files.Add(s1); } Hashtable includedfncs = new Hashtable(); LoadSourceFromReader(includefilename, r, files, includedfncs, true, ""); // Neem nu de gelezen functies over in onze eigen lijst, check op dubbelen. foreach (FunctionInfo fi in includedfncs.Values) { if (functioninfo.ContainsKey(fi.Name)) { FunctionInfo otherone = functioninfo[fi.Name] as FunctionInfo; throw new DuplicateFunctionDefinitionException(fi.DeclaredAt, fi.Name, otherone.DeclaredAt); } functioninfo.Add(fi.Name, fi); } //.. en alweer klaar. linenr++; s = reader.ReadLine(); continue; } if (sLineTrim.StartsWith("--") || sLineTrim == "") { linenr++; s = reader.ReadLine(); continue; } } if (includefile) { if (s.Trim() != "") { throw new IncludeFilesCanOnlyContainFunctionsException(new SourceCodeContext(conceptname, filename, linenr)); } } sc.Add(linenr.ToString() + ":" + s); s = reader.ReadLine(); linenr++; } reader.Close(); return(sc); }