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;
}
}
}