/// <summary> /// Sets global LPHP-variables inside the given file /// </summary> /// <param name="pFileContent">Target file</param> /// <returns>File-content with set (global) variables</returns> private static string SetGlobalVariables(string pFileContent) { // Read in functions and variable calls foreach (Match ItemMatch in Regex.Matches(pFileContent, @"\$\$\??(?!\{)\w*(\([\S\s]*?\))?")) { // Check if the matched object is not a function-call if (!Regex.IsMatch(ItemMatch.Value, @"\$\$\??(?!\{)\w*(\([\S\s]*?\))")) { string key = ItemMatch.Value.TrimStart('$'); try { if (key.StartsWith("?") && !globalVariables.ContainsKey(key.TrimStart('?'))) { pFileContent = pFileContent.Replace(ItemMatch.Value, ""); } else { pFileContent = pFileContent.Replace(ItemMatch.Value, globalVariables[key.TrimStart('?')].ToString()); } } catch { LPHPDebugger.PrintError("Unknown variable in " + currentCompileFile); LPHPDebugger.PrintError("Variable: " + key.TrimStart('?')); throw new ApplicationException(); } } } return(pFileContent); }
/// <summary> /// Prepares LPHP-instructions for processing /// </summary> private static void PrepareInstructions() { foreach (string instruction in instructionSessionBuffer.ToArray()) { // [SET] Local variable if (Regex.IsMatch(instruction, @"^set\s*?\S*?\s*?=\s*?[\S\s]*?$")) { string varName = Regex.Replace(instruction, @"^set\s*|\s*?=[\S\s]*?$", ""); object varValue = ValueParser(Regex.Replace(instruction, @"^set[\S\s]*?=\s*", "")); if (!localVariables.ContainsKey(varName)) { localVariables.Add(varName, varValue); } else { LPHPDebugger.PrintWarning("Warning in " + currentCompileFile + ":"); LPHPDebugger.PrintWarning("Variable \"" + varName + "\" gets assigned more than once!"); throw new ApplicationException(); } } // [GLOB] Global variable else if (Regex.IsMatch(instruction, @"^glob\s*?\S*?\s*?=\s*?[\S\s]*?$")) { string varName = Regex.Replace(instruction, @"^glob\s*|\s*?=[\S\s]*?$", ""); object varValue = ValueParser(Regex.Replace(instruction, @"^glob[\S\s]*?=\s*", "")); if (!globalVariables.ContainsKey(varName)) { globalVariables.Add(varName, varValue); } else { LPHPDebugger.PrintWarning("Warning in " + currentCompileFile + ":"); LPHPDebugger.PrintWarning("Global variable \"" + varName + "\" gets assigned more than once!"); throw new ApplicationException(); } } // Ignored instructions else if ( Regex.IsMatch(instruction, @"^Layout\s*?=\s*?\""[\S\s]*?\""$") || Regex.IsMatch(instruction, @"^NoCompile\s*?=\s*?(true|false)$") ) { // Ignore. } // Invalid instruction else { LPHPDebugger.PrintError("*** Error in \"" + currentCompileFile + "\" ***"); LPHPDebugger.PrintError($"Unknown instruction: \"{instruction}\""); throw new ApplicationException(); } // Remove entry from List instructionSessionBuffer.Remove(instruction); } }
/// <summary> /// Saves a file as php /// </summary> /// <param name="pOriginalFilename">Original LPHP filename (Source-filename)</param> /// <param name="pFileContent">Processed filecontent of the source LPHP-file</param> private static void SaveFile(string pOriginalFilename, string pFileContent) { string targetFileXML = Path.Combine(Path.GetDirectoryName(pOriginalFilename), Path.GetFileNameWithoutExtension(pOriginalFilename) + ".php"); string targetFileMIN = Path.Combine(Path.GetDirectoryName(pOriginalFilename), Path.GetFileNameWithoutExtension(pOriginalFilename) + ".min.php"); // Delete old, unused generated php files try { File.Delete(targetFileXML); } catch { } try { File.Delete(targetFileMIN); } catch { } bool fileGenerated = false; string selectedFileExt; if ((bool)COMPOPT["MIN_OUTPUT_ENABLED"]) { // If only min is selected, no min gets added to the extension if ((bool)COMPOPT["XML_OUTPUT_ENABLED"]) { selectedFileExt = targetFileMIN; } else { selectedFileExt = targetFileXML; } using (StreamWriter sw = new StreamWriter(selectedFileExt)) { sw.Write(AddCopyrightNotice(pFileContent, true)); sw.Close(); } fileGenerated = true; } // TODO: Output XML-Formated document if ((bool)COMPOPT["XML_OUTPUT_ENABLED"]) { using (StreamWriter sw = new StreamWriter(targetFileXML)) { sw.Write(LPHPHTML2XMLFormatter(AddCopyrightNotice(pFileContent, false))); sw.Close(); } fileGenerated = true; } if (!fileGenerated) { LPHPDebugger.PrintError("Warning: No Output-Type selected!"); LPHPDebugger.PrintError("Please set MIN_OUTPUT_ENABLED and/or XML_OUTPUT_ENABLED to \"True\" in LPHP.ini"); throw new ApplicationException(); } }
/// <summary> /// Loads an LPHP content-file and merges it with an LPHP layout-file /// </summary> /// <param name="pFileContent">File-content of the source-file</param> /// <param name="pLayoutFile">Path to the layout-file</param> /// <param name="pParentFilePath">Parent file-path of the source</param> /// <returns>Page-contents combined with layout</returns> private static string LoadIntoLayout(string pFileContent, string pLayoutFile, string pParentFilePath) { if (pLayoutFile != null) { string layoutFilePath; try { layoutFilePath = Path.Combine(Path.GetDirectoryName(pParentFilePath), pLayoutFile); } catch { LPHPDebugger.PrintError("*** Error in \"" + currentCompileFile + "\" ***"); LPHPDebugger.PrintError("\"" + pLayoutFile + "\" is not a valid file-path."); throw new ApplicationException(); } if (File.Exists(layoutFilePath)) { // Load Layout and execute RenderBody string layoutContent = LoadFile(layoutFilePath); if (layoutContent.Contains("$$RenderBody()")) { pFileContent = layoutContent.Replace("$$RenderBody()", pFileContent); } else { LPHPDebugger.PrintError("*** Error in \"" + currentCompileFile + "\" ***"); LPHPDebugger.PrintError("RenderBody() doesn't get called! Layout-Pages require exactly one call to RenderBody()!"); throw new ApplicationException(); } } else { LPHPDebugger.PrintError("*** Error in \"" + currentCompileFile + "\" ***"); LPHPDebugger.PrintError("Could not load Layout-Page: "); LPHPDebugger.PrintError("\"" + layoutFilePath + "\" does not exist."); throw new ApplicationException(); } } return(pFileContent); }
/// <summary> /// Initializes the LPHP-Compiler /// </summary> public static void Init() { COMPOPT = new Dictionary <string, object> { { "REMOVE_HTML_COMMENTS", true }, { "MIN_OUTPUT_ENABLED", true }, { "XML_OUTPUT_ENABLED", false }, { "UI_LAST_PROJECT_PATH", "" }, { "ENABLE_CONSOLE_LOG", true } }; if (!File.Exists(LPHPIniFile)) { SaveConfig(); } else { using (StreamReader sr = new StreamReader(LPHPIniFile)) { string line; while ((line = sr.ReadLine()) != null) { if (!string.IsNullOrEmpty(line)) { string[] keyValueEntry = line.Split('='); try { COMPOPT[keyValueEntry[0]] = Convert.ChangeType(keyValueEntry[1], COMPOPT[keyValueEntry[0]].GetType()); } catch { LPHPDebugger.PrintError("*** Error in \"LPHP.ini\" ***"); LPHPDebugger.PrintError("Unknown key: " + keyValueEntry[0]); LPHPDebugger.PrintError("Please check or delete the config-file and restart the program."); throw new ApplicationException(); } } } } } }
/// <summary> /// Loads and includes pages included by the RenderPage-Function /// </summary> /// <param name="pFileContent">File-content of the source-file</param> /// <param name="pParentFilePath">>Parent file-path of the source</param> /// <returns>Source file-contents with rendered pages included</returns> private static string LoadRenderPages(string pFileContent, string pParentFilePath) { // Find RenderPage()-Command, and load Child-File foreach (Match ItemMatch in Regex.Matches(pFileContent, @"\$\$RenderPage\(\""[\S\s]*?\""\)")) { string originalRenderPageCommand = ItemMatch.Value; string renderPageFile = Regex.Match(ItemMatch.Value, @"\""[\S\s]*?\""").Value.Replace("\"", ""); string renderPageFilePath = ""; try { renderPageFilePath = Path.Combine(Path.GetDirectoryName(pParentFilePath), renderPageFile); } catch { LPHPDebugger.PrintError("*** Error in \"" + currentCompileFile + "\" ***"); LPHPDebugger.PrintError("\"" + renderPageFile + "\" is not a valid file-path."); throw new ApplicationException(); } if (File.Exists(renderPageFilePath)) { pFileContent = pFileContent.Replace(originalRenderPageCommand, LoadFile(renderPageFilePath)); } else { LPHPDebugger.PrintError("*** Error in \"" + currentCompileFile + "\" ***"); LPHPDebugger.PrintError("Could not render Page: "); LPHPDebugger.PrintError("\"" + renderPageFilePath + "\" does not exist."); throw new ApplicationException(); } } return(pFileContent); }
/// <summary> /// Constantly checks the given directory for changes and re-compiles as soon as a change is detected. /// </summary> /// <param name="pWatchFolder">Folder to watch</param> private static int Run(bool pRunInfinite = true) { try { if (!string.IsNullOrEmpty(ProjectRoot)) { if (pRunInfinite) { lphpFiles = new Dictionary <string, string>(); } do { foreach (string filePath in Directory.EnumerateFiles(ProjectRoot, "*.*", SearchOption.AllDirectories)) { try { if (Path.GetExtension(filePath) == ".lphp") { using (var md5 = MD5.Create()) { try { using (var stream = File.OpenRead(filePath)) { byte[] md5Bytes = md5.ComputeHash(stream); string md5Hash = Encoding.UTF8.GetString(md5Bytes, 0, md5Bytes.Length); if (!lphpFiles.ContainsKey(md5Hash)) { foreach (KeyValuePair <string, string> entry in lphpFiles.ToArray()) { if (entry.Value == filePath) { lphpFiles[entry.Key] = null; } } foreach (var item in lphpFiles.Where(kvp => kvp.Value == null).ToList()) { lphpFiles.Remove(item.Key); } lphpFiles.Add(md5Hash, filePath); LPHPDebugger.PrintMessage($"\r\nChange detected in {filePath}..."); LPHPCompiler.Run(lphpFiles); LPHPDebugger.PrintSuccess($"Compiled successfully!"); } } } catch (IOException) { LPHPDebugger.PrintWarning("Can't keep up! Compilation-Cycle skipped."); } } } } catch { LPHPDebugger.PrintWarning("Compilation aborted. Please fix all errors shown above and try again."); if (!pRunInfinite) { return(-2); } } } Thread.Sleep(100); }while (pRunInfinite); } else { LPHPDebugger.PrintError("*** LPHP Watchdog Error ***"); LPHPDebugger.PrintError("Please provide a path to the target folder and try again."); if (!pRunInfinite) { return(-1); } } } catch { LPHPDebugger.PrintError("*** Error reading the directory ***"); LPHPDebugger.PrintError("Please make sure the given directory exists."); if (!pRunInfinite) { return(-1); } } return(0); }