Пример #1
0
    private void _eName_TextChanged(object sender, EventArgs e)
    {
        string name = _eName.Text;
        var    a    = new List <(string name, string code)>();

        int nWild = 0; for (int i = 0; i < name.Length; i++)

        {
            switch (name[i])
            {
            case '*':
            case '?': nWild++; break;
            }
        }

        if (name.Length > 0 && (nWild == 0 || name.Length - nWild >= 2))
        {
            string sql;
            if (name.Contains(' '))
            {
                sql = $"SELECT * FROM api WHERE name in ('{string.Join("', '", name.RegexFindAll(@"\b[A-Za-z_]\w\w+", 0))}')";
            }
            else if (name.FindAny("*?") >= 0)
            {
                sql = $"SELECT * FROM api WHERE name GLOB '{name}'";
            }
            else
            {
                sql = $"SELECT * FROM api WHERE name = '{name}'";
            }
            try {
                using var stat = _db.Statement(sql);
                //APerf.First();
                while (stat.Step())
                {
                    a.Add((stat.GetText(0), stat.GetText(1)));
                }
                //APerf.NW(); //30 ms cold, 10 ms warm. Without index.
            }
            catch (SLException ex) { ADebug.Print(ex.Message); }
        }

        string code = "";

        if (a.Count != 0)
        {
            code = a[0].code;
            if (a.Count > 1)
            {
                code = string.Join(code.Starts("internal const") ? "\r\n" : "\r\n\r\n", a.Select(o => o.code));
            }
            code += "\r\n";
        }
        _code.ZSetText(code);
    }
Пример #2
0
    /// <summary>
    /// Creates SQLite database containing Windows API declarations.
    /// </summary>
    public static void CreateWinapi(string csDir = @"Q:\app\Au\Other\Api", string dataDir = @"Q:\app\Au\Other\Data")
    {
        Cursor.Current = Cursors.WaitCursor;
        string dbFile = dataDir + @"\winapi.db";

        AFile.Delete(dbFile);

        string s = File.ReadAllText(csDir + @"\Api.cs");

        using var d     = new ASqlite(dbFile);
        using var trans = d.Transaction();
        d.Execute("CREATE TABLE api (name TEXT, def TEXT)");         //note: no PRIMARY KEY. Don't need index.
        using var statInsert = d.Statement("INSERT INTO api VALUES (?, ?)");

        string rxType     = @"(?ms)^(?:\[[^\r\n]+\r\n)*internal (?:struct|enum|interface|class) (\w+)[^\r\n\{]+\{(?:\}$|.+?^\})";
        string rxFunc     = @"(?m)^(?:\[[^\r\n]+\r\n)*internal (?:static extern|delegate) \w+\** (\w+)\(.+;$";
        string rxVarConst = @"(?m)^internal (?:const|readonly|static) \w+ (\w+) =.+;$";

        foreach (var m in s.RegexFindAll(rxType))
        {
            _Add(m);
        }
        foreach (var m in s.RegexFindAll(rxFunc))
        {
            _Add(m);
        }
        foreach (var m in s.RegexFindAll(rxVarConst))
        {
            _Add(m);
        }

        void _Add(RXMatch m)
        {
            statInsert.Bind(1, m[1].Value);
            statInsert.Bind(2, m.Value);
            statInsert.Step();
            statInsert.Reset();
        }

        trans.Commit();
        d.Execute("VACUUM");

        Program.Settings.db_copy_winapi = dbFile;

        AOutput.Write("CreateWinapi done.");
        Cursor.Current = Cursors.Arrow;
    }
Пример #3
0
    static void _CreateRef(string dbFile, string dir1, string dir2)
    {
        AFile.Delete(dbFile);
        using var d     = new ASqlite(dbFile);
        using var trans = d.Transaction();
        d.Execute("CREATE TABLE ref (name TEXT PRIMARY KEY, data BLOB)");
        using var statInsert = d.Statement("INSERT OR REPLACE INTO ref VALUES (?, ?)");

        _AddDir(dir1, "WindowsBase", "System.Drawing");
        _AddDir(dir2);

        trans.Commit();
        d.Execute("VACUUM");

        AOutput.Write("Created " + dbFile);

        void _AddDir(string dir, params string[] skip)
        {
            foreach (var f in AFile.EnumDirectory(dir))
            {
                if (f.IsDirectory)
                {
                    continue;
                }
                if (!f.Name.Ends(".dll", true))
                {
                    continue;
                }
                var asmName = f.Name.RemoveSuffix(4);
                if (skip.Contains(asmName))
                {
                    continue;
                }
                _AddFile(asmName, f.FullPath);
                //break;
            }
        }

        void _AddFile(string asmName, string asmFile)
        {
            //AOutput.Write(asmName);
            statInsert.Bind(1, asmName);
            statInsert.Bind(2, File.ReadAllBytes(asmFile));
            statInsert.Step();
            statInsert.Reset();
        }
    }
Пример #4
0
 protected internal override string GetDocumentationForSymbol(string documentationMemberID, CultureInfo preferredCulture, CancellationToken cancellationToken = default)
 {
     if (_db != null)
     {
         lock (_db) {                    //sometimes not in main thread
             try {
                 _stat ??= _db.Statement("SELECT xml FROM doc WHERE name=?");
                 if (_stat.Bind(1, documentationMemberID).Step())
                 {
                     return(_stat.GetText(0));
                 }
                 //ADebug.Print(documentationMemberID);
             }
             catch (SLException ex) { ADebug.Print(ex.Message); }
             finally { _stat?.Reset(); }
         }
     }
     return(null);
 }
Пример #5
0
            /// <summary>
            /// Creates documentation provider for assembly <i>asmPath</i>.
            /// Returns null if its xml file does not exist.
            /// Returns _DocumentationProvider if xml file is big and found or successfully created and successfully loaded database for it.
            /// Else returns XmlDocumentationProvider.
            /// </summary>
            public static DocumentationProvider Create(string asmPath)
            {
                if (s_d.TryGetValue(asmPath, out var dp))
                {
                    return(dp);
                }

                var xmlPath = Path.ChangeExtension(asmPath, "xml");

                if (!AFile.GetProperties(xmlPath, out var px))
                {
                    return(null);
                }

                if (px.Size >= 10_000)
                {
                    var md5    = new Au.Util.AHash.MD5(); md5.Add(xmlPath.Lower());
                    var dbPath = AFolders.ThisAppTemp + md5.Hash.ToString() + ".db";
                    try {
                        if (!AFile.GetProperties(dbPath, out var pd) || pd.LastWriteTimeUtc != px.LastWriteTimeUtc)
                        {
                            //ADebug.Print($"creating db: {asmPath}  ->  {dbPath}");
                            AFile.Delete(dbPath);
                            using (var d = new ASqlite(dbPath)) {
                                using var trans = d.Transaction();
                                d.Execute("CREATE TABLE doc (name TEXT PRIMARY KEY, xml TEXT)");
                                using var statInsert = d.Statement("INSERT INTO doc VALUES (?, ?)");

                                var xr = AExtXml.LoadElem(xmlPath);
                                foreach (var e in xr.Descendants("member"))
                                {
                                    var name = e.Attr("name");

                                    //remove <remarks> and <example>.
                                    foreach (var v in e.Descendants("remarks").ToArray())
                                    {
                                        v.Remove();
                                    }
                                    foreach (var v in e.Descendants("example").ToArray())
                                    {
                                        v.Remove();
                                    }

                                    using var reader = e.CreateReader();
                                    reader.MoveToContent();
                                    var xml = reader.ReadInnerXml();
                                    //AOutput.Write(name, xml);

                                    statInsert.BindAll(name, xml).Step();
                                    statInsert.Reset();
                                }
                                trans.Commit();
                                d.Execute("VACUUM");
                            }
                            File.SetLastWriteTimeUtc(dbPath, px.LastWriteTimeUtc);
                        }
                        var db = new ASqlite(dbPath, SLFlags.SQLITE_OPEN_READONLY);                         //never mind: we don't dispose it on process exit
                        s_d[asmPath] = dp = new _DocumentationProvider {
                            _db = db
                        };
                        return(dp);
                    }
                    catch (Exception ex) { ADebug.Print(ex.ToStringWithoutStack()); }
                }
                return(XmlDocumentationProvider.CreateFromFile(xmlPath));
            }
Пример #6
0
    static void _CreateDoc(string dbFile, string dir1, string dir2)
    {
        AFile.Delete(dbFile);
        using var d     = new ASqlite(dbFile, sql: "PRAGMA page_size = 8192;");     //8192 makes file smaller by 2-3 MB.
        using var trans = d.Transaction();
        d.Execute("CREATE TABLE doc (name TEXT PRIMARY KEY, xml TEXT)");
        using var statInsert = d.Statement("INSERT INTO doc VALUES (?, ?)");
        using var statDupl   = d.Statement("SELECT xml FROM doc WHERE name=?");
        var haveRefs = new List <string>();
        var uniq     = new Dictionary <string, string>();    //name -> asmName

        //using var textFile = File.CreateText(Path.ChangeExtension(dbFile, "txt")); //test. Compresses almost 2 times better than db.

        _AddDir(dir1, "WindowsBase");
        _AddDir(dir2);

        statInsert.BindAll(".", string.Join("\n", haveRefs)).Step();

        trans.Commit();
        d.Execute("VACUUM");

        AOutput.Write("Created " + dbFile);

        void _AddDir(string dir, params string[] skip)
        {
            foreach (var f in AFile.EnumDirectory(dir))
            {
                if (f.IsDirectory)
                {
                    continue;
                }
                if (!f.Name.Ends(".xml", true))
                {
                    continue;
                }
                var asmName = f.Name.RemoveSuffix(4);
                if (skip.Contains(asmName))
                {
                    continue;
                }
                if (!AFile.ExistsAsFile(dir + asmName + ".dll"))
                {
                    AOutput.Write("<><c 0x808080>" + f.Name + "</c>");
                    continue;
                }
                _AddFile(asmName, f.FullPath);
                //break;
            }
        }

        void _AddFile(string asmName, string xmlFile)
        {
            //AOutput.Write(asmName);
            haveRefs.Add(asmName);
            var xr = AExtXml.LoadElem(xmlFile);

            foreach (var e in xr.Descendants("member"))
            {
                var name = e.Attr("name");

                //remove <remarks> and <example>. Does not save much space, because .NET xmls don't have it.
                foreach (var v in e.Descendants("remarks").ToArray())
                {
                    v.Remove();
                }
                foreach (var v in e.Descendants("example").ToArray())
                {
                    v.Remove();
                }

                using var reader = e.CreateReader();
                reader.MoveToContent();
                var xml = reader.ReadInnerXml();
                //AOutput.Write(name, xml);

                //textFile.WriteLine(name); textFile.WriteLine(xml); textFile.WriteLine("\f");

                if (uniq.TryGetValue(name, out var prevRef))
                {
                    if (!statDupl.Bind(1, name).Step())
                    {
                        throw new AuException();
                    }
                    var prev = statDupl.GetText(0);
                    if (xml != prev && asmName != "System.Linq")
                    {
                        AOutput.Write($"<>\t{name} already defined in {prevRef}\r\n<c 0xc000>{prev}</c>\r\n<c 0xff0000>{xml}</c>");
                    }
                    statDupl.Reset();
                }
                else
                {
                    statInsert.BindAll(name, xml).Step();
                    uniq.Add(name, asmName);
                }
                statInsert.Reset();
            }
        }
    }