/// <summary> /// Converts the analyzer output to a PluginFile data structure /// </summary> /// <param name="lvi">The list view item</param> /// <param name="txt">The analyzer output</param> /// <returns>The converted PluginFile</returns> private Data.PluginFile makePlugin(ListViewItem lvi, string[] txt, Dictionary <Data.CalleeSlot, List <KeyValuePair <string, string> > > calleeDefs) { Data.PluginFile p = new Data.PluginFile(); p.Filename = lvi.Text; p.IsCore = lvi.ImageIndex == 1; List <Data.Module> mods = new List <Data.Module>(); List <Data.Call> calls = new List <Data.Call>(); Data.Module mod = null; Data.Call call = null; Data.ParamSlot pslot = null; Data.CalleeSlot ceslot = null; Data.CallerSlot crslot = null; string desc = null; string calltypename = null; foreach (string l in txt) { if (desc == null) { if (!l.StartsWith("mma-")) { continue; } if (l.StartsWith("mma-lt:")) { // intentionally empty } else if (l.StartsWith("mma-core:")) { // intentionally empty } else if (l.StartsWith("mma-module:")) { if (mod != null) { mods.Add(mod); mod = null; } if (call != null) { calls.Add(call); call = null; } pslot = null; ceslot = null; crslot = null; mod = new Data.Module(); mod.Name = l.Substring(11); } else if (l.StartsWith("mma-call:")) { if (mod != null) { mods.Add(mod); mod = null; } if (call != null) { calls.Add(call); call = null; } pslot = null; ceslot = null; crslot = null; call = new Data.Call(); call.Name = l.Substring(9); } else if (l.StartsWith("mma-desc:")) { desc = l.Substring(9); } else if (l.StartsWith("mma-func:")) { if (call == null) { continue; } string[] fn = call.FunctionName; if (fn == null) { fn = new string[1]; } else { Array.Resize(ref fn, fn.Length + 1); } fn[fn.Length - 1] = l.Substring(9); call.FunctionName = fn; } else if (l.StartsWith("mma-pslot:")) { if (mod == null) { continue; } Data.ParamSlot[] ps = mod.ParamSlots; if (ps == null) { ps = new Data.ParamSlot[1]; } else { Array.Resize(ref ps, ps.Length + 1); } pslot = new Data.ParamSlot(); ceslot = null; crslot = null; ps[ps.Length - 1] = pslot; mod.ParamSlots = ps; pslot.Name = l.Substring(10); } else if (l.StartsWith("mma-typeinfo:")) { if (pslot == null) { continue; } string hex = l.Substring(13); pslot.Type = pslot.TypeFromTypeInfo( Enumerable.Range(0, hex.Length) .Where(x => x % 2 == 0) .Select(x => Convert.ToByte(hex.Substring(x, 2), 16)) .ToArray()); } else if (l.StartsWith("mma-defval:")) { if (pslot == null) { continue; } if (pslot.Type == null) { continue; // ack } if (pslot.Type is Data.ParamTypeValueBase) { ((Data.ParamTypeValueBase)pslot.Type).ParseDefaultValue(l.Substring(11)); } } else if (l.StartsWith("mma-ceslot:")) { if (mod == null) { continue; } Data.CalleeSlot[] ces = mod.CalleeSlots; if (ces == null) { ces = new Data.CalleeSlot[1]; } else { Array.Resize(ref ces, ces.Length + 1); } pslot = null; ceslot = new Data.CalleeSlot(); crslot = null; ces[ces.Length - 1] = ceslot; mod.CalleeSlots = ces; ceslot.Name = l.Substring(11); calleeDefs[ceslot] = new List <KeyValuePair <string, string> >(); } else if (l.StartsWith("mma-compcalltype:")) { if (ceslot == null) { continue; } calltypename = l.Substring(17); } else if (l.StartsWith("mma-compcallfunc:")) { if (ceslot == null) { continue; } if (calltypename == null) { continue; // ack } calleeDefs[ceslot].Add(new KeyValuePair <string, string>(calltypename.ToLowerInvariant(), l.Substring(17).ToLowerInvariant())); calltypename = null; } else if (l.StartsWith("mma-crslot:")) { if (mod == null) { continue; } Data.CallerSlot[] crs = mod.CallerSlots; if (crs == null) { crs = new Data.CallerSlot[1]; } else { Array.Resize(ref crs, crs.Length + 1); } pslot = null; ceslot = null; crslot = new Data.CallerSlot(); crs[crs.Length - 1] = crslot; mod.CallerSlots = crs; crslot.Name = l.Substring(11); } else if (l.StartsWith("mma-compcall:")) { if (crslot == null) { continue; } string[] cc = crslot.CompatibleCalls; if (cc == null) { cc = new string[1]; } else { Array.Resize(ref cc, cc.Length + 1); } cc[cc.Length - 1] = l.Substring(13); crslot.CompatibleCalls = cc; } else { Debug.WriteLine("not yet supported:" + l); } } else { if (l.StartsWith("mma-desc-end")) { // description complete! if (pslot != null) { pslot.Description = desc; } else if (ceslot != null) { ceslot.Description = desc; } else if (crslot != null) { crslot.Description = desc; } else if (mod != null) { mod.Description = desc; } else if (call != null) { call.Description = desc; } desc = null; } else { desc += "\n"; desc += l; } } } if (mod != null) { mods.Add(mod); mod = null; } if (call != null) { calls.Add(call); call = null; } p.Modules = mods.ToArray(); p.Calls = calls.ToArray(); return(p); }
public List <Data.PluginFile> Analyze(string path) { string bitness = IntPtr.Size == 4 ? "32" : "64"; List <MegaMolInterface> mmis = new List <MegaMolInterface>(); mmis.Add(new MegaMolCoreInterface()); List <String> dlls = FileFinder.FindFiles(path, "*.mmplg"); foreach (string dll in dlls) { if (dll.Contains("win" + bitness) && // very large cinema indeed #if !DEBUG ! #endif dll.Contains(bitness + "d")) { mmis.Add(new MegaMolPluginInterface(dll)); } } foreach (MegaMolInterface mmi in mmis) { Data.PluginFile pf = new Data.PluginFile(); pf.Filename = mmi.Filename; pf.IsCore = mmi is MegaMolCoreInterface; List <Data.Call> calls = new List <Data.Call>(); Debug.WriteLine(mmi.Filename + " has " + mmi.ModuleCount + " modules and " + mmi.CallCount + " calls."); for (int x = 0; x < mmi.CallCount; x++) { Data.Call c = new Data.Call(); c.Name = mmi.CallName(x); c.Description = mmi.CallDescription(x); List <string> functions = new List <string>(); for (int y = 0; y < mmi.FunctionCount(x); y++) { string s = mmi.FunctionName(x, y); functions.Add(s); } c.FunctionName = functions.ToArray(); calls.Add(c); } pf.Calls = calls.ToArray(); plugins.Add(pf); } foreach (MegaMolInterface mmi in mmis) { Data.PluginFile pf = FindPluginByFileName(mmi.Filename); if (pf == null) { continue; } List <Data.Module> modules = new List <Data.Module>(); for (int x = 0; x < mmi.ModuleCount; x++) { Data.Module m = new Data.Module(); m.Name = mmi.ModuleName(x); m.Description = mmi.ModuleDescription(x); ModuleDescriptionObj mdo = mmi.ModuleDescriptionObj(x); List <Data.ParamSlot> parms = new List <Data.ParamSlot>(); for (int y = 0; y < mdo.ParamSlotCount; y++) { Data.ParamSlot p = new Data.ParamSlot(); p.Name = mdo.ParameterSlot(y).Name; p.Description = mdo.ParameterSlot(y).Description; Byte[] typeInfo = mdo.ParameterSlot(y).TypeInfo; p.Type = this.TypeFromTypeInfo(typeInfo); if (p.Type is Data.ParamTypeValueBase) { ((Data.ParamTypeValueBase)p.Type).ParseDefaultValue(mdo.ParameterSlot(y).DefaultValue); } parms.Add(p); } if (parms.Count > 0) { m.ParamSlots = parms.ToArray(); } else { m.ParamSlots = null; } List <Data.CalleeSlot> calleeSlots = new List <Data.CalleeSlot>(); for (int y = 0; y < mdo.CalleeSlotCount; y++) { Dictionary <string, List <string> > callTypes = new Dictionary <string, List <string> >(); CalleeSlotDescription csd = mdo.CalleeSlot(y); for (int z = 0; z < csd.CallbackCount; z++) { if (!callTypes.ContainsKey(csd.CallType(z))) { callTypes.Add(csd.CallType(z), new List <string>()); } callTypes[csd.CallType(z)].Add(csd.FunctionName(z)); } // now find out if these fit any calls Data.CalleeSlot cs = new Data.CalleeSlot(); // TODO this is bullshit! why? cs.Name = csd.Name; cs.Description = csd.Description; List <string> compCalls = new List <string>(); foreach (string calltype in callTypes.Keys) { Data.Call c = FindCallByName(calltype); if (c != null) { bool ok = true; foreach (string fun in c.FunctionName) { ok &= callTypes[calltype].Contains(fun); } if (ok) { compCalls.Add(calltype); } } } if (compCalls.Count > 0) { cs.CompatibleCalls = compCalls.ToArray(); } else { cs.CompatibleCalls = null; } calleeSlots.Add(cs); } if (calleeSlots.Count > 0) { m.CalleeSlots = calleeSlots.ToArray(); } else { m.CalleeSlots = null; } List <Data.CallerSlot> callerSlots = new List <Data.CallerSlot>(); for (int y = 0; y < mdo.CallerSlotCount; y++) { Data.CallerSlot callerSlot = new Data.CallerSlot(); CallerSlotDescription csd = mdo.CallerSlot(y); callerSlot.Name = csd.Name; callerSlot.Description = csd.Description; List <string> compCalls = new List <string>(); for (int z = 0; z < csd.CompatibleCallCount; z++) { string callName = csd.CompatibleCall(z); if (FindCallByName(callName) != null) { compCalls.Add(callName); } } callerSlot.CompatibleCalls = compCalls.ToArray(); callerSlots.Add(callerSlot); } if (callerSlots.Count > 0) { m.CallerSlots = callerSlots.ToArray(); } else { m.CallerSlots = null; } modules.Add(m); } pf.Modules = modules.ToArray(); } return(plugins); }