using System; using System.Collections; using System.IO; using System.Xml; /** * * Should now handle localization somewhat better. * */ namespace CosmosDocumentifier { /// /// Summary description for LuaHandler. /// public class LuaHandler { public LuaHandler() { } private static string GetDefinitionOrRawString(StringDefinition stringDefinition, string key) { if(stringDefinition.Definitions.ContainsKey(key)) { return stringDefinition.Definitions[key].ToString(); } else { if(key.StartsWith("TEXT(")) { int startIndex = key.IndexOf("(")+1; int endIndex = key.LastIndexOf(")"); if(endIndex > -1) { string qwe = key.Substring(startIndex, endIndex-startIndex); if(stringDefinition.Definitions.ContainsKey(qwe)) { return stringDefinition.Definitions[qwe].ToString(); } } } if(key.StartsWith("\"")) { string qwe = key.Substring(key.IndexOf("\""), key.LastIndexOf("\"")); if(stringDefinition.Definitions.ContainsKey(qwe)) { return stringDefinition.Definitions[qwe].ToString(); } } return key; } } private static string StripFnutts(string str) { // strips the "s (vulgarly called "fnuttar" in Swedish) if(str.StartsWith("\"")) { str = str.Substring(1); } if(str.EndsWith("\"")) { str = str.Substring(0, str.Length-1); } return str; } public static string FUNCTION_NAME = "Cosmos_RegisterConfiguration"; public static int FUNCTION_NAME_PARAMETER_INDEX = 2; public static int FUNCTION_DESCRIPTION_PARAMETER_INDEX = 3; public static int FUNCTION_ID_PARAMETER_INDEX = 0; public static int FUNCTION_NAME_PARANTHESIS_MAX_DISTANCE = 1; private static string GetThingyAsXML(string format, StringDefinition stringDefinition, FunctionContainer fc) { try { string name = "N/A"; string description = "N/A"; string id = "N/A"; try { id = StripFnutts(GetDefinitionOrRawString(stringDefinition, fc.FunctionArgs[FUNCTION_ID_PARAMETER_INDEX].ToString())); name = StripFnutts(GetDefinitionOrRawString(stringDefinition, fc.FunctionArgs[FUNCTION_NAME_PARAMETER_INDEX].ToString())); description = StripFnutts(GetDefinitionOrRawString(stringDefinition, fc.FunctionArgs[FUNCTION_DESCRIPTION_PARAMETER_INDEX].ToString())); } catch(Exception) { } if(name == "End of Options") { return null; } return string.Format(format, name, description, id); } catch(Exception ex) { Console.WriteLine("Eeka!"); Console.WriteLine(fc.ToString()); throw ex; } } /// /// The main entry point for the application. /// [STAThread] static void Main(string[] args) { if(args.Length == 0) { Console.WriteLine(" usage : CosmosDocumentifier [Cosmos_RegisterConfiguration function name] [Name parameter index] [Description parameter index] [id parameter index]"); Console.WriteLine(); Console.WriteLine("Name parameter index - the number of the name parameter (0 based)"); Console.WriteLine("Description parameter index - the number of the description parameter (0 based)"); Console.WriteLine(); Console.WriteLine("Example usage : "); Console.WriteLine(); Console.WriteLine("Code is stored in MegaOption(id, name, blahblah, description, blah blah)"); Console.WriteLine("CosmosDocumentifier Interface MegaOption 1 3 0"); return; } string dir = "..\\..\\Interface"; if(args.Length > 0) { dir = args[0]; if(dir.EndsWith("\\")) { dir = dir.Substring(0, dir.Length-1); } } string function = FUNCTION_NAME; if(args.Length > 1) { function = args[1]; } if(args.Length > 2) { try { FUNCTION_NAME_PARAMETER_INDEX = int.Parse(args[2]); } catch(FormatException) { } catch(OverflowException) { } } if(args.Length > 3) { try { FUNCTION_DESCRIPTION_PARAMETER_INDEX = int.Parse(args[3]); } catch(FormatException) { } catch(OverflowException) { } } if(args.Length > 4) { try { FUNCTION_ID_PARAMETER_INDEX = int.Parse(args[4]); } catch(FormatException) { } catch(OverflowException) { } } ArrayList arrayList = GetFunctionCallAndParametersFromDirectory(dir, function); //ArrayList arrayList = GetFunctionCallAndParametersFromFile(dir + "\\AddOns\\AutoEquip\\AutoEquip.lua", function); try { StringDefinition stringDefinition = StringDefinition.LoadDefinition(dir + "\\Cosmos\\CosmosStrings.lua"); stringDefinition.AddDefinition(dir + "\\AddOns\\Cosmos\\CosmosStrings.lua"); stringDefinition.AddDefinitions(dir, "localization.lua"); stringDefinition.AddDefinitions(dir, "localisation.lua"); StreamWriter streamWriter = File.CreateText("CosmosFeaturesDocumentation.xml"); streamWriter.WriteLine(""); bool hasStartedSeperator = false; FunctionContainer fc = null; string str = null; for(int i = 0 ; i < arrayList.Count ; i++) { fc = arrayList[i] as FunctionContainer; if(fc != null) { str = null; string type = null; if(fc.FunctionArgs.Count > 1) { type = fc.FunctionArgs[1].ToString(); if((type == "\"SEPARATOR\"") || (type == "SEPARATOR")) { str = ""; str = GetThingyAsXML("\t
", stringDefinition, fc); if(str != null) { if(hasStartedSeperator) { streamWriter.WriteLine("\t\t"); streamWriter.WriteLine("\t
"); } streamWriter.WriteLine(str); streamWriter.WriteLine("\t\t"); str = null; hasStartedSeperator = true; } } else { str = ""; str += GetThingyAsXML("\t\t\t\r\n\t\t\t\t{2}\r\n\t\t\t\t{0}\r\n\t\t\t\t{1}\r\n\t\t\t", stringDefinition, fc); } } if(str != null) { streamWriter.WriteLine(str); } } } if(hasStartedSeperator) { streamWriter.WriteLine("\t\t"); streamWriter.WriteLine("\t"); } streamWriter.WriteLine("
"); streamWriter.Flush(); streamWriter.Close(); XmlDocument xmlDocument = HTMLify.GetXML("CosmosFeaturesDocumentation.xml"); streamWriter = File.CreateText("CosmosFeaturesDocumentation.html"); streamWriter.WriteLine(HTMLify.GenerateHTML(xmlDocument)); streamWriter.Flush(); streamWriter.Close(); } catch(Exception ex) { Console.Out.WriteLine(ex.ToString()); } } public static ArrayList GetFunctionCallAndParametersFromDirectory(string directory, string function) { ArrayList arrayList = new ArrayList(); string[] files = Directory.GetFiles(directory); foreach(string file in files) { foreach(FunctionContainer fc in GetFunctionCallAndParametersFromFile(file, function)) { arrayList.Add(fc); } } string[] subdirs = Directory.GetDirectories(directory); foreach(string subdir in subdirs) { foreach(FunctionContainer fc in GetFunctionCallAndParametersFromDirectory(subdir, function)) { arrayList.Add(fc); } } return arrayList; } public static ArrayList GetFunctionCallAndParametersFromFile(string file, string function) { if(file.IndexOf("CosmosTest.lua") > -1) { return new ArrayList(); } if(file.IndexOf("Autotrade.lua") > -1) { // AutoTrade contains evil wonky code that shows up all wrong. // Might be fixed sometime. // Evil persons should keep from doing their own nifty functions and suffer like // good mod authors. :D return new ArrayList(); } int dotIndex = file.LastIndexOf("."); if(dotIndex > -1) { string extension = file.Substring(dotIndex+1); switch(extension) { case("lua"): break; case("xml"): break; default: return new ArrayList(); break; } } StreamReader streamReader = null; try { streamReader = File.OpenText(file); string luaFile = StripComments(streamReader.ReadToEnd()); // StreamWriter streamWriter = File.CreateText(file + ".cleaned"); // streamWriter.WriteLine(luaFile); // streamWriter.Flush(); // streamWriter.Close(); streamReader.Close(); return GetFunctionCallAndParameters(luaFile, function); } catch(IOException ex) { Console.Error.WriteLine(ex.ToString()); } return new ArrayList(); } private static string StripComments(string luaCode) { StringWriter stringWriter = new StringWriter(); bool singleLineComment = false; bool multiLineComment = false; int index = 0; while(index < luaCode.Length) { if(multiLineComment) { if((luaCode[index] == ']') && (luaCode.Length > index) && (luaCode[index+1] == ']')) { multiLineComment = false; } index++; continue; } if((luaCode[index] == '[') && (luaCode.Length > index) && (luaCode[index+1] == '[')) { multiLineComment = true; index++; continue; } if(singleLineComment) { if(luaCode[index] == '\n') { singleLineComment = false; } index++; continue; } if((luaCode[index] == '-') && (luaCode.Length > index) && (luaCode[index+1] == '-')) { singleLineComment = true; index++; continue; } stringWriter.Write(luaCode[index]); //strippedString += luaCode[index]; index++; } return stringWriter.ToString().Trim(); } public static ArrayList GetFunctionCallAndParameters(string luaFile, string function) { ArrayList functionArgsArrayList = null; int curArgsStartIndex = 0; int index = 0; int paranthesis = 0; bool shouldBreakOut = false; ArrayList arrayList = new ArrayList(); while(index > -1) { index = luaFile.IndexOf(function, index); if(index != -1) { // special fix to prevent it from picking up the declaration of the function itself if(luaFile.LastIndexOf("function", index, index) == index-9) { index += function.Length; continue; } // Console.Out.Write("Found at offset " + index); index += function.Length; shouldBreakOut = false; for(int i = 0 ; i < FUNCTION_NAME_PARANTHESIS_MAX_DISTANCE ; i++) { if(luaFile[index+i] == '(') { paranthesis = 1; index += i; index++; break; } else { if(!char.IsWhiteSpace(luaFile[index+i])) { // Console.Out.WriteLine(" dismissed."); shouldBreakOut = true; break; } } } if(shouldBreakOut) { continue; } // Console.Out.WriteLine(" verified."); functionArgsArrayList = new ArrayList(); curArgsStartIndex = index; bool isInFnutt = false; while((index < luaFile.Length) && (paranthesis > 0)) { if((luaFile[index] == '\"') && (index > 0) && (luaFile[index-1] != '\\')) { if(isInFnutt) { isInFnutt = false; } else { isInFnutt = true; } } if(isInFnutt) { index++; continue; } if(luaFile[index] == '(') { paranthesis++; } else if(luaFile[index] == ')') { paranthesis--; if(paranthesis == 0) { functionArgsArrayList.Add(luaFile.Substring(curArgsStartIndex, (index-curArgsStartIndex)).Trim()); curArgsStartIndex = index + 1; } } else if(luaFile[index] == ',') { functionArgsArrayList.Add(luaFile.Substring(curArgsStartIndex, (index-curArgsStartIndex)).Trim()); curArgsStartIndex = index + 1; } index++; } arrayList.Add(new FunctionContainer(function, functionArgsArrayList)); } } return arrayList; } } }