D语言中国主页  D语言编辑器SciTE4D   DWin库 D语言官方网站
D语言编译器1.x最新版 OpenSource   Tango   webnews  Wiki

查看完整版本: D语言一键打开标识符identifier所在文件

yidabu 2007-7-4 09:54

D语言一键打开标识符identifier所在文件

D语言一键打开标识符identifier所在文件知识若不分享 实在没有意义 http://www.d-programming-language-china.org 20070703点击下面网址查看原文:http://bbs.d-programming-language-china.org/thread-631-1.htmlD语言一键打开标识符identifier所在文件代码        d-programming-language-china.org 下载了D语言关于windows api的头文件:        http://www.prowiki.org/wiki4d/wiki.cgi?WindowsAPI        然后打算把一段C++的windows程序翻译为D格式,但windows api函数定义在哪个头文件里呢?逐个去手工搜索是很讨厌的事情。        于是立即写了一个D程序来自动搜索定义identifer所在的文件。        [Copy to clipboard] [ - ]CODE:                                /*                Author: yidabu, D china, http://www.d-programming-language-china.org                Date:    20070706                DMD version:    1.018                Dhelp version:    0.1                compile:                    1 download ini.d from http://www.dprogramming.com/ini.php (thanks Chris Miller)                    2 download win32 header from http://www.prowiki.org/wiki4d/wiki.cgi?WindowsAPI                    3 download dfl from http://www.dprogramming.com/dfl.php (thanks Chris Miller)                    4 compile instruction:    dmd dhelp.d shellapi.d -O -release                                useage:                    step1 first run dhelp.exe                    will create dhelp.ini and dkeys.txt, edit the config to fit you need.                        searchdir=directory to search definition                        searchexclude=regular expression pattern of excluded search path                        scite=fullpath of scite.exe                        pattern=regular expression pattern of search definition, except for 'searchword'                        dchm=fullpath of dchm.chm                        dkeys.txt = D and phobos keywords                    step2 add to d.properties of scite                        command.3.*.d=yourpath\dhelp.exe $(FilePath) $(CurrentWord)                        command.name.3.*.d=go to definition                        command.subsystem.3.*.d=2                        command.shortcut.3.*.d=Ctrl+F1                        command.save.before.3.*.d=1                    step3 add to SciTEUser.properties of scite                        check.if.already.open=1                                todo:    how to keep dhelp.chm window ?                */                                import ydb.ini;                import std.file;                import std.regexp;                import std.string;                import std.stream : File;                import std.utf : toUTF16z;                import win32.shellapi : ShellExecuteW;                import win32.winuser;        //for SW_SHOWMAXIMIZED                import win32.winbase;        //for FreeLibrary,LoadLibraryW                import win32.winnt;        //HANDLE                import std.path;                import std.c.stdio;        //for getch();                import dfl.application;    //for startupPath                                import std.typetuple;        //dllimport                import std.traits;        //dllimport                                //for htmlhelp, from htmlhelp.h                const uint HH_DISPLAY_TOPIC    =    0x0000;                const uint HH_HELP_FINDER    =    0x0000;    // WinHelp equivalent                const uint HH_DISPLAY_TOC    =    0x0001;                const uint HH_DISPLAY_INDEX    =    0x0002;                const uint HH_DISPLAY_SEARCH =    0x0003;                const uint HH_SET_WIN_TYPE    =    0x0004;                const uint HH_GET_WIN_TYPE    =    0x0005;                const uint HH_GET_WIN_HANDLE =    0x0006;                const uint HH_ENUM_INFO_TYPE =    0x0007;    // Get Info type name, call repeatedly to enumerate, -1 at end                const uint HH_SET_INFO_TYPE    =    0x0008;    // Add Info type to filter.                const uint HH_SYNC    =    0x0009;                const uint HH_DISPLAY_TEXT_POPUP    = 0x000E;    // display string resource id or text in a popup window                const uint HH_HELP_CONTEXT    = 0x000F;    // display mapped numeric value in dwData                const uint HH_TP_HELP_CONTEXTMENU = 0x0010;    // text popup help, same as WinHelp HELP_CONTEXTMENU                const uint HH_TP_HELP_WM_HELP    = 0x0011;    // text popup help, same as WinHelp HELP_WM_HELP                                pragma(lib,"ydb.lib");        //for ydb.ini, you can comment this and add ini.d to compile instruction                pragma(lib,"dfl_debug.lib");    //for dfl.application                                                int main(string[] args)                {                    int result;                    try                    {                        assert(args.length > 2, "args length < 3, now exit");                        Dhelp sf = new Dhelp(args[1], args[2]);                        result = sf.dhelp();                        getch();    //for keep dhelp.chm window only, need a better solution                    }                    catch(Exception e)                    {                        printf("catch %.*s\n",e.msg);                        result = 1;                    }                    return result;                }                //=main                                                class Dhelp                {                    // from dhelp.ini                    string searchdir;        //directory to search                    string searchexclude;    //regular expression of excluded path                    string scite;            //fullpath of scite.exe                    string dkeys;        //                    //regular expression of search pattern                    string pattern = r"^\s*([\w\[\]*]+\s+)+([\w\[\]*]+\s*,\s*)*(searchword)\s*[:,{;=(]";                    string dchm;            //full path of D help chm                                    string exedir;                    string inipath;                    string dkeyspath;        //fullpath of dkeys.txt                                    Ini ini;                                    string filename;        //current d source file full path;                    string searchword;        //identifier to search                    string postfixword;    //postfix of searchword                                    this(string filename, string searchword)                    {                        dkeys = r" abstract alias align asm assert auto body bool break byte case cast catch cdouble cent cfloat char class const continue creal dchar debug default delegate delete deprecated do double else enum export extern false final finally float for foreach    function goto idouble if ifloat import in inout int interface invariant ireal is lazy long macro mixin module new null out override package pragma private protected public real ref return scope short static struct super switch synchronized template this throw true try typedef typeid typeof ubyte ucent uint ulong union unittest ushort version void volatile wchar while with string wstring dstring                                loader    path    demangle                 invariant time    utf                 etc switch    format    syserror dmain2 arraycat                 com bind    testgc    outofmemory typetuple zip                 ctype math2 random regexp    signals    fenv                 object    asserterror traits memset linuxextern typeinfo trace                 boxer date string intrinsic locale stdlib    stdio                    stdint windows    moduleinit adi unittest socket                 deh2    switcherr internal    phobos                 uni    system gclinux arraycast                 qsort cpuid bitarray compiler conv std charset pthread                 aaA obj openrj gcstats zlib cast iunknown gc                    llmath array stdarg    registry dateparse                 gcstub    outbuffer perf cover gcold linux                 gcbits    md5    winsock file stat                 math socketstream cmath2    win32 thread crc32 gcx                 alloca gamma uri aApplyR base64 stream process mmfile                 qsort2 stddef cstream metastrings                                opCmp opEquals factory find getHash equals compare swap                 encodeLength decodeLength Tuple append                 prepend BoundFunc opIndex init opAnd                 opOr opXor opSub opAndAssign opOrAssign opXorAssign opSubAssign opCatAssign                 unboxable boxArray boxArrayToArguments toInt setSourceDir setDestDir setMerge isalnum isalpha iscntrl                 isdigit islower ispunct isspace isupper isxdigit isgraph isprint                 isascii tolower toupper fetestexcept feraiseexcept feclearexcept fesetround fesetprec                 fegetenv fesetenv fegetexceptflag fesetexceptflag feholdexcept feupdateenv setlocale acos                 asin atan atan2 acosh asinh                 atanh exp exp2 expm1 frexp                 ilogb ldexp log10 log1p log2 modf                 scalbn scalbln cbrt fabs hypot pow sqrt erf                 erfc lgamma tgamma ceil floor nearbyint lrint                 llrint lround llround trunc fmod remainder remquo                 copysign nan nextafter nexttoward fdim fmax fmin isgreater isgreaterequal isless islessequal islessgreater isunordered tmpnam fopen                 _fsopen freopen fseek ftell fgets fgetc fflush fclose                 fputs fputc _fputchar ungetc fread fwrite                 fprintf vfprintf vprintf sprintf vsprintf scanf fscanf sscanf                 setbuf setvbuf remove rename perror fgetpos fsetpos getw                 putw ferror feof clearerr rewind                 fileno unlink fdopen filesize tempnam _wtmpnam fgetws                 fputws wprintf fwprintf vwprintf vfwprintf swprintf vswprintf wscanf                 fwscanf swscanf fgetwc fputwc ungetwc    fwide div alloca calloc unsetenv atof                 itoa mblen memcpy memmove strcpy strncpy strncat strcoll                 strncmp strxfrm memchr strchr strcspn strpbrk strrchr strspn                 strstr strtok memset strerror strlen strcmp strcat memcmp                 memicmp parse toISO8601YearWeek YearFromTime inLeapYear MonthFromTime DateFromTime WeekDay                 UTCtoLocalTime LocalTimetoUTC toString toUTCString toDateString toTimeString toDtime                 toDosFileTime demangle getSize                 getTimes exists getAttributes isfile isdir chdir mkdir rmdir                 listdir toMBSz addRoot removeRoot addRange removeRange                 hasPointers hasNoPointers setTypeInfo malloc realloc extend capacity setGCHandle                 bsf bsr bt btc btr bts bswap inp                 outp conj rndtol rndtonl isnan isfinite isnormal issubnormal isinf signbit feqrel                 poly sum printDigest digestToString finish opSlice opIndexAssign getField findField                 hasField getRecordsContainingField reserve fill0 alignSize                 spread getExt getName getBaseName getDirName getDrive                 defaultExt addExt isabs join fncharmatch fnmatch expandTilde system                 execv    rfind split search opCall                 replace replaceOld emit connect disconnect getProtocolByName getProtocolByType                 getServiceByName getHostByName getHostByAddr isSet                 bind listen shutdown send sendTo receive receiveFrom                 getOption setOption select readBlock writeBlock                 writef writefln fwritef fwritefln readln readExact                 readString readStringW vreadf writeExact writeLine writeLineW writeString writeStringW copyFrom seekSet position source                 create readBOM fixBO fixBlockBO writeBOM iswhite atoi                 toStringz capitalize                 capwords repeat splitlines stripl chomp                 chop ljustify zfill replaceSlice insert count expandtabs                 entab maketrans translate format sformat                 inPattern countchars removechars squeeze succ isNumeric                 soundex abbrev column wrap isEmail isURL                 wait setPriority isUniLower isUniUpper toUniLower toUniUpper isUniAlpha decodeComponent encodeComponent isValidDchar stride toUCSindex                 toUTFindex validate toUTF8 toUTF16 toUTF32 fromMBSz                 addMember deleteMember adler32 crc32 compress uncompress ";                                        exedir = Application.startupPath();        //dfl.application.                        inipath = exedir ~ r"\dhelp.ini";                        dkeyspath = exedir ~ r"\dkeys.txt";                        if (std.file.exists(dkeyspath))                        {                            dkeys = cast(string) std.file.read(dkeyspath);                        }                        else                        {                            std.file.write(dkeyspath, dkeys);                        }                        string t;        //temp                                        ini = new Ini(inipath);                        if (ini["config"] is null) ini.addSection("config");                        if ( ini["config"]["searchdir"] is null ) ini["config"]["searchdir"] = "";                        if ( ini["config"]["searchexclude"] is null ) ini["config"]["searchexclude"] = "";                        if ( ini["config"]["scite"] is null )    ini["config"]["scite"] = "";                        t = ini["config"]["pattern"];                        if (t is null || t.length < 10 ) ini["config"]["pattern"] = pattern;                        if ( ini["config"]["dchm"] is null ) ini["config"]["dchm"] = "";                        ini.save();                                        searchdir = ini["config"]["searchdir"];                        assert( searchdir && searchdir.length > 2 && std.file.exists(searchdir), "searchdir not exists" );                        t = ini["config"]["searchexclude"];                        if ( t && t.length > 2 ) searchexclude = t;                        scite = ini["config"]["scite"];                        assert(scite && scite.length > 2 && std.file.exists(scite), "scite not exists");                        t = ini["config"]["pattern"];                        if ( t && t.length > 10 ) pattern = t;                        t = ini["config"]["dchm"];                        if (t && t.length > 5 && std.file.exists(t)) dchm = t;                                        assert(filename && std.file.exists(filename), "not exists" ~ filename);                        assert(searchword && searchword.length > 2, "searchword length < 3");                        if (std.string.find(searchword,".") == 0) searchword = searchword[1..$]; //.word replace to word                        this.filename = filename;                        this.searchword = searchword;                                        auto m = std.regexp.search(searchword, r"\w+$");                        assert(m,"wrong searchword " ~ searchword);                        postfixword = m.match(0);                        printf("filename %.*s \n",filename);                        printf("searchword %.*s \n",searchword);                        //~ printf("postfix of searchword %.*s \n",postfixword);                    }                                    this(){}                                    ~this()                    {                        delete ini;                    }                                                    int dhelp()                    {                        int result;                        string src;            //source of file                        string searchpath;        //path of import module                        string pattern2;        //regular expression pattern of searchword                        try                        {                            //if a import module                            if ( std.string.find(searchword,".") > 0 )                            {                                src = cast(string) std.file.read(filename);                                string p = r"^\s*import.*?[\W]" ~ std.string.replace(searchword,".",r"\.") ~ r"\s*[,:;]";                                if (std.regexp.search(src, p, "mig"))                                {                                    searchpath = std.string.replace(searchword, ".",r"\");                                }                            }                                            //if dhelp.chm exists, check if searchword is a d keyword                            if (dchm && !searchpath)                            {                                DllImport!("hhctrl.ocx", "HtmlHelpW",                                    void* function(void* hwndCaller, wchar* pszFile, uint uCommand, uint dwData)) HtmlHelp;                                //if a d keywords,                                if (std.regexp.search(dkeys, r"\s" ~ postfixword ~ r"\s"))                                {    //open dhelp.chm                                    //how to keep the window of dhelp.chm?                                    HtmlHelp(cast(void*)0,toUTF16z(dchm), HH_DISPLAY_INDEX , cast(uint)toUTF16z(postfixword));                                    debug printf("a D keyword %.*s \n", postfixword);                                    return 0;                                }                            }                                            bool callback(DirEntry* de)                            {                                if (de.isdir)                                {                                    if ( searchexclude && std.regexp.search(de.name, searchexclude,"i") )                                    {                                        return true;                                    }                                    std.file.listdir(de.name, &callback);                                }                                else                                {                                    if ( std.string.icmp(getExt(de.name),"d") )                                    {                                        return true;        // .d file only                                    }                                    if ( searchpath )    //if searchword is a import module                                    {                                        if (std.string.ifind(de.name, searchpath ~ ".d") != -1 )//open import file                                        {                                            string dirname = std.path.getDirName(de.name);                                            string basename = std.path.getBaseName(de.name);                                            ShellExecuteW(null, toUTF16z("open"), toUTF16z(scite), toUTF16z(" -open:" ~ basename), toUTF16z(dirname), SW_SHOWMAXIMIZED);                                            return false;                                        }                                        else                                            return true;//continue search                                    }                                                    pattern2 = std.string.replace( pattern,"searchword",postfixword);                                    int i;        //line index                                    std.stream.File src = new std.stream.File(de.name);                                    do                                    {                                        i++;                                        if (auto m = std.regexp.search(src.readLine(), pattern2))                                        {                                            string dirname = std.path.getDirName(de.name);                                            string basename = std.path.getBaseName(de.name);                                            ShellExecuteW(null, toUTF16z("open"), toUTF16z(scite), toUTF16z("-open:" ~ basename ~ " -goto:" ~ std.string.toString(i)), toUTF16z(dirname), SW_SHOWMAXIMIZED);                                            printf("%.*s %.*s %d \n", de.name, m.match(0), i);                                            break;                                        }                                    }while(!src.eof);                                                }//de.isfile                                return true;                            }//callback                                            std.file.listdir(searchdir, &callback);                        }//try                        catch(Exception e)                        {                            printf("dhelp catch %.*s\n", e.msg);                            result = 1;                        }                        finally                        {                            printf("end \n");                        }                        return result;                    }                    //=dhelp                                    unittest{                        printf("dhelp unittest begin \n");                        Dhelp sf = new Dhelp();                        string pattern;                                        void test(string s, string searchword, bool direction = true)                        {                            if (std.string.find(searchword,".") >= 0) return;    //not test module here                            string pattern = std.string.replace(sf.pattern, "searchword", searchword);                            //~ debug printf("pattern %.*s \n",pattern);                            auto m = std.regexp.search(s,pattern);                            if (!direction)                            {                                assert(!m, searchword);                                printf("ok, not matched %.*s \n", searchword);                            }                            else                            {                                assert(m && (m.match(3) == searchword), searchword);                                printf("ok, matched %.*s \n", m.match(1));                            }                        }                                        test("DWORD numread;", "numread");                        test(" const FVIRTKEY    = 1;", "FVIRTKEY");                        test(" template MAKEINTRESOURCE_T (WORD i)", "MAKEINTRESOURCE_T");                        test(" const CREATEPROCESS_MANIFEST_RESOURCE_ID    = MAKEINTRESOURCE_T!(1);", "CREATEPROCESS_MANIFEST_RESOURCE_ID");                        test("struct TRACKMOUSEEVENT {", "TRACKMOUSEEVENT");                        test("alias TRACKMOUSEEVENT* LPTRACKMOUSEEVENT;", "LPTRACKMOUSEEVENT");                        test("alias MEASUREITEMSTRUCT* PMEASUREITEMSTRUCT, LPMEASUREITEMSTRUCT;", "PMEASUREITEMSTRUCT");                        test("alias MEASUREITEMSTRUCT* PMEASUREITEMSTRUCT, LPMEASUREITEMSTRUCT;", "LPMEASUREITEMSTRUCT");                        test("HWND CreateDialogA(HINSTANCE h, LPCSTR n, HWND w, DLGPROC f)", "CreateDialogA");                        test("interface IEnumFORMATETC : public IUnknown {", "IEnumFORMATETC");                        test("struct BYTE_SIZEDARR {", "BYTE_SIZEDARR");                        test("struct GUID {    ", "GUID");                                        test("PMEASUREITEMSTRUCT, LPMEASUREITEMSTRUCT;", "LPMEASUREITEMSTRUCT", false);                        test("result.lenght = MultiByteToWideChar(", "MultiByteToWideChar", false);                        test("    ERROR_DS_DUP_SCHEMA_ID_GUID,", "GUID", false);                        test(" char[] getGuid (),", "Guid", false);                        test("struct BYTE_SIZEDARR {", "BYTE", false);                        test("interface IEnumFORMATETC : public IUnknown {", "IUnknown",false);                        test("extern IID IID_IGlobalInterfaceTable;", "IID", false);                        test("int DlgDirListA(HWND, LPSTR, int, int, UINT);", "UINT", false);                        test("HWND CreateDialogA(HINSTANCE h, LPCSTR n, HWND w, DLGPROC f)", "HINSTANCE", false);                                        printf("dhelp unittest end \n\n");                    }//unittest                }                //Dhelp                                                //dynamic load dll                //by oldrev                private static class ModuleManager                {                    private static HANDLE[string]    m_modules;                                    private this()                    {}                                    static public ~this()                    {                        foreach(h; m_modules)                        {                            FreeLibrary(h);//winbase                        }                    }                                    private static HANDLE registerModule(string name)                    {                        string lname = tolower(name);                        HANDLE h = LoadLibraryW(toUTF16z(lname));                        if(h is null)                            throw new Exception("Failed to load DLL: " ~ name);                        m_modules[lname] = h;                        return h;                    }                                    public static HANDLE getHandle(string name)                    {                        return m_modules[name];                    }                                    public static ProcType getSymbol(ProcType)(string moduleName, string procName)                    {                        HANDLE handle = null;    //winnt                        if(moduleName in m_modules)                            handle = m_modules[moduleName];                        else                            handle = registerModule(moduleName);                                        assert(handle !is null);                        ProcType proc = cast(ProcType)GetProcAddress(handle, toStringz(procName));//winbase                        if(proc is null)                            throw new Exception("Cannot to get the address of " ~ procName);                        return proc;                    }                }                                struct DllImport(string ModuleName, string ProcName, FT)                {                    extern(Windows) alias ReturnType!(FT)                        function(ParameterTypeTuple!(FT))    FunctionType;                    alias DllImport!(ModuleName, ProcName, FT) SelfType;                    //FIXME: avoid the CTFE?                    private FunctionType m_funcPtr = null;                    public ReturnType!(FunctionType) opCall(ParameterTypeTuple!(FunctionType) args)                    {                        if(m_funcPtr is null)                            m_funcPtr = ModuleManager.getSymbol!(FunctionType)(ModuleName, ProcName);                        return m_funcPtr(args);                    }                }        实际应用        把光标置于要D源文件某处,然后按预定义的快捷键:        如果是导入模块,就自动在scite打开对应的文件        如果是d的关键词,就自动打开dhelp.chm        否则就go to definition file        现在 http://bbs.d-programming-language-china.org 写windows api相关程序就方便多了,找一段参考c++代码,用dhelp.exe快速查出要导入的header,再转换成D语法。        或者在写程序时要查看定义出处,或者要查帮助文档,都是非常方便。( lastupdate:20070706 最新文章请访问http://www.d-programming-language-china.org )关于一大步成功社区:yidabu提倡在交流中学习,在分享中提高收集感兴趣的知识,写下心得,通过网络与别人一起分享理解一点就实践一步,收获什么就分享什么,成功就是这样一点点一步步累积起来的网络只是一个工具,只有自己身心提高才是实实在在的。d-programming-language-china.org为大家提供一个学习交流各种知识的平台

sleets 2007-7-4 14:49

这个网站的广告真是要命哦
页: [1]
查看完整版本: D语言一键打开标识符identifier所在文件