Thread overview
Doxygen
May 17, 2004
Stewart Gordon
May 17, 2004
Ant
May 17, 2004
Ben Hinkle
May 17, 2004
Hauke Duden
May 18, 2004
J C Calvarese
May 18, 2004
Hauke Duden
May 17, 2004
I briefly tried Doxygen the other day.  I soon noticed that it was omitting quite large chunks of my code from the documentation.

Obviously version 1.3.7 doesn't by itself support D after all, and so it's trying to parse my code as if it's C++.  Hence it's missing stuff like attribute blocks and the fact that class/union/struct/enum definitions aren't semicolon-terminated in D.

Has anyone actually coded up the tweak to make Doxygen understand D?  Or are the D projects that use Doxygen built around Doxygen's limitations?

TIA

Stewart.

-- 
My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment.  Please keep replies on the 'group where everyone may benefit.
May 17, 2004
In article <c8aoqi$6o0$1@digitaldaemon.com>, Stewart Gordon says...
>
>I briefly tried Doxygen the other day.  I soon noticed that it was omitting quite large chunks of my code from the documentation.
>
>Obviously version 1.3.7 doesn't by itself support D after all, and so it's trying to parse my code as if it's C++.  Hence it's missing stuff like attribute blocks and the fact that class/union/struct/enum definitions aren't semicolon-terminated in D.
>
>Has anyone actually coded up the tweak to make Doxygen understand D?  Or are the D projects that use Doxygen built around Doxygen's limitations?
>
>TIA
>

adding ";" after enums and stuff
(probably templates and structs, can't remember details)
seems to help a bit.

Ant


May 17, 2004
There is a filter for D that also helps:
http://www.sun-inet.or.jp/~yaneurao/dlang/lib/ddoc.zip
Searching the old newsgroup will probably turn up other filters that people
had attached to posts.

-Ben

"Stewart Gordon" <smjg_1998@yahoo.com> wrote in message news:c8aoqi$6o0$1@digitaldaemon.com...
> I briefly tried Doxygen the other day.  I soon noticed that it was omitting quite large chunks of my code from the documentation.
>
> Obviously version 1.3.7 doesn't by itself support D after all, and so it's trying to parse my code as if it's C++.  Hence it's missing stuff like attribute blocks and the fact that class/union/struct/enum definitions aren't semicolon-terminated in D.
>
> Has anyone actually coded up the tweak to make Doxygen understand D?  Or are the D projects that use Doxygen built around Doxygen's limitations?
>
> TIA
>
> Stewart.
>
> -- 
> My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment.  Please keep replies on the 'group where everyone may benefit.


May 17, 2004
Stewart Gordon wrote:

> I briefly tried Doxygen the other day.  I soon noticed that it was omitting quite large chunks of my code from the documentation.
> 
> Obviously version 1.3.7 doesn't by itself support D after all, and so it's trying to parse my code as if it's C++.  Hence it's missing stuff like attribute blocks and the fact that class/union/struct/enum definitions aren't semicolon-terminated in D.
> 
> Has anyone actually coded up the tweak to make Doxygen understand D?  Or are the D projects that use Doxygen built around Doxygen's limitations?

Doxygen 1.3.7 only has basic support for D. It basically treats D as a variant of C++ with a little Java and C# mixed in (this allows it to recognize interfaces, for example).

To get good results you need to combine it with a filtering program that translates most of the remaining D syntax quirks into something more C++-ish. The program is called dfilter.d and it was posted in this newsgroup a while back. Make sure you get the modified version for the new Doxygen, which was posted sometime at the end of the last year. I can repost it when I get home (don't have it here at work).

Hauke

May 18, 2004
Hauke Duden wrote:
> Stewart Gordon wrote:
> 
>> I briefly tried Doxygen the other day.  I soon noticed that it was omitting quite large chunks of my code from the documentation.
>>
>> Obviously version 1.3.7 doesn't by itself support D after all, and so it's trying to parse my code as if it's C++.  Hence it's missing stuff like attribute blocks and the fact that class/union/struct/enum definitions aren't semicolon-terminated in D.
>>
>> Has anyone actually coded up the tweak to make Doxygen understand D?  Or are the D projects that use Doxygen built around Doxygen's limitations?
> 
> 
> Doxygen 1.3.7 only has basic support for D. It basically treats D as a variant of C++ with a little Java and C# mixed in (this allows it to recognize interfaces, for example).
> 
> To get good results you need to combine it with a filtering program that translates most of the remaining D syntax quirks into something more C++-ish. The program is called dfilter.d and it was posted in this newsgroup a while back. Make sure you get the modified version for the new Doxygen, which was posted sometime at the end of the last year. I can repost it when I get home (don't have it here at work).
> 
> Hauke

I think I found your earlier message (I'm sure you'll correct me if I'm mistaken):  http://www.digitalmars.com/drn-bin/wwwnews?D/20989


And here's the attached code...

import std.file, std.ctype, std.c.stdio;

char [] data; /* Data. */
char *c; /* Current point. */
char *s; /* Previous filter point. */
char *e; /* End of the data. */
char *p; /* Start of this token. */

/* Read in a token. */
char [] token ()
{
restart:
    p = c;

    if (c >= e)
        return null;

    if (isalpha (*c) || *c == '_')
    {
        for (c ++; c < e; c ++)
            if (!isalnum (*c) && *c != '_')
                break;

        return p [0 .. (int) (c - p)];
    }

    if (*c == ' ' || *c == '\r' || *c == '\n' || *c == '\t')
    {
        c ++;
        goto restart;
    }

    if (*c == '"')
    {
        for (c ++; c < e; c ++)
            if (*c == '\\')
                c ++;
            else if (*c == '"')
            {
                c ++;
                break;
            }
        goto restart;
    }

    if (*c == '\'')
    {
        for (c ++; c < e; c ++)
            if (*c == '\'')
            {
                c ++;
                break;
            }
        goto restart;
    }

    if (c < e - 1)
    {
        if (*c == '/' && c [1] == '/')
        {
            for (c += 2; ; c ++)
                if (c >= e || *c == '\n')
                {
                    c ++;
                    goto restart;
                }
        }

        if (*c == '/' && c [1] == '*')
        {
            for (c += 2; ; c ++)
                if (c >= e - 1 || (*c == '*' && c [1] == '/'))
                {
                    c += 2;
                    goto restart;
                }
        }

        if (*c == '/' && c [1] == '+')
        {
            int depth = 1;

            for (c += 2; ; c ++)
                if (c >= e - 1)
                    goto restart;
                else if (*c == '/' && c [1] == '+')
                {
                    c += 2;
                    depth ++;
                }
                else if (*c == '+' && c [1] == '/')
                {
                    c += 2;
                    depth --;
                    if (!depth)
                        goto restart;
                }
        }
    }

    c ++;
    return p [0 .. 1];
}

/* Print all text to this point and set s to the current point. */
void flush (char *p)
{
    fwrite (s, (int) (p - s), 1, stdout);
    s = c;
}

/* Consume a "{ ... }" or "(xxx) { ... }" block. */
void skipBlock (char *p)
{
    char *o = s;

    flush (p);

    int depth = 0;
    char [] t = token ();

    if (t == "(")
    {
        while (1)
        {
            t = token ();
            if (t == ")" || t == null)
                break;
        }
        t = token ();
    }

    if (t != "{")
    {
        s = p;
        flush (c);
        return;
    }

    while (1)
    {
        if (t == null)
            break;
        if (t == "{")
            depth ++;
        if (t == "}")
        {
            depth --;
            if (depth == 0)
                break;
        }

        t = token ();
    }

    s = c;
}

int main (char [] [] args)
{
    if (args.length == 1)
    {
        printf ("%.*s FILENAME\n\nPreprocesses the file in preparation for Doxygen.\n", args [0]);
        return 1;
    }

    data = (char []) read (args [1]);
    c = s = data;
    e = s + data.length;

    char [] t;
    char [] [] protectRecord;
    char [] protect = "public";
    char [] [] brackets;
    char [] nextOpenBracket;
    char [] nextSemiColon;
    bit insideBrackets;

    while (1)
    {
        t = token ();
        if (t == null)
        {
            flush (c);
            return 0;
        }

        switch (t)
        {
            /* Remove these keywords. */
            case "body":
                flush (p);
                s = c;
                break;

            /* Remove these blocks. */
            case "unittest":
            case "invariant":
            case "in":
            case "out":
                skipBlock (p);
                break;

            /* Remove "keyword:" but only if it is followed with a colon. */
            case "override":
            case "abstract":
            case "final":
                flush (p);
                if ((t = token ()) == ":")
                    s = c;
                break;

            case ";":
                flush (c);
                printf ("%.*s", nextSemiColon);
                nextSemiColon = null;
                break;

            /* "keyword" without "keyword:" into "keyword: ... { ... } antikeyword:" */
            case "public":
            case "private":
            case "protected":
                flush (p);
                if (token () == ":")
                {
                    printf ("%.*s", t);
                    protect = t;
                    break;
                }

                if (t != protect)
                {
                    printf ("%.*s: ", t);
                    s = p;
                    nextOpenBracket = protect ~ ":";
                    nextSemiColon = protect ~ ":";
                }
                break;

            /* Modify into "package". */
            /*Not necessary anymore
				case "module":
                flush (p);
                printf ("package ", nextSemiColon);
                s = c;
                break;*/

            /* Modify into import X.Y.*. */
			/* Not necessary anymore
            case "import":
                flush (p);
                printf ("import ", nextSemiColon);

                while ((t = token ()) != null)
                {
                    if (t == ";")
                    {
                        printf (";");
                        break;
                    }
                    else
                        printf ("%.*s", t);
                }
                s = c;
                break;*/

            /* Remove "extern (...)". */
            case "extern":
                flush (p);
                if ((t = token ()) != "(")
                {
                    c = p;
                    break;
                }

                while ((t = token ()) != null)
                    if (t == ")")
                        break;
                s = c;
                break;

            /* "alias" into "typedef". */
            case "alias":
                flush (p);
                printf ("typedef");
                s = c;
                break;

            /* "instance" into "typedef". */
            case "instance":
                flush (p);
                printf ("typedef");
                s = c;

                while ((t = token ()) != null)
                    if (t == "(")
                    {
                        flush (p);
                        printf ("<");
                        s = c;
                    }
                    else if (t == ")")
                    {
                        flush (p);
                        printf (">");
                        s = c;
                        break;
                    }

                break;

            case "{":
                brackets ~= nextOpenBracket;
                nextOpenBracket = null;
                break;

            /* "}" into "};" */
            case "}":
                if (protectRecord.length)
                {
                    protect = protectRecord [protectRecord.length - 1];
                    protectRecord.length = protectRecord.length - 1;
                }

                flush (c);
                printf (";");
                if (brackets.length && brackets [brackets.length - 1])
                {
                    printf (" %.*s", brackets [brackets.length - 1]);
                    brackets = brackets [0 .. brackets.length - 1];
                }
                break;

            /* "class ... {" into "class ... { public:". */
            /* Not necessary anymore
			case "class":
            case "interface":
            {
                bit colon = false;

                flush (p);

				printf ("class");

				protectRecord ~= protect;
				protect = "public";

                while ((t = token ()) != null)
                {
                restart:
                    if (t == ":" && !colon)
                    {
                        colon = true;
                        t = token ();
                        if (t != "public" && t != "private" && t != "protected")
                        {
                            flush (p);
                            s = p;
                            printf ("public ");
                            goto restart;
                        }
                    }
                    else if (t == ";")
                        break;
                    else if (t == "{")
                    {
                        flush (c);		
						printf (" public:");
                        break;
                    }
                }
                break;
            }*/

            /* "template name (x)" into "template namespace name <x>". */
            case "template":
                protectRecord ~= protect;
                protect = "public";

                flush (c);
                printf (" class");
                while ((t = token ()) != null)
                    if (t == "(")
                    {
                        flush (p);
                        printf ("<");
                        s = c;
                    }
                    else if (t == ")")
                    {
                        flush (p);
                        printf (">");
                        s = c;
                        break;
                    }

                while ((t = token ()) != null)
                    if (t == "{")
                    {
                        flush (c);
                        printf (" public:");
                        break;
                    }
                    else if (t == ";")
                        break;
                break;

            /* "delegate (...) name" into "(*name) (...)". */
            case "delegate":
                flush (p);
                s = c;
                while ((t = token ()) != null)
                    if (t == ")")
                    {
                        t = token ();
                        printf ("(*%.*s)", t);
                        flush (p);
                        s = c;
                        break;
                    }
                break;

            default:
                break;
        }
    }
}






-- 
Justin (a/k/a jcc7)
http://jcc_7.tripod.com/d/
May 18, 2004
J C Calvarese wrote:
> Hauke Duden wrote:
> 
>> Stewart Gordon wrote:
>>
>>> I briefly tried Doxygen the other day.  I soon noticed that it was omitting quite large chunks of my code from the documentation.
>>>
>>> Obviously version 1.3.7 doesn't by itself support D after all, and so it's trying to parse my code as if it's C++.  Hence it's missing stuff like attribute blocks and the fact that class/union/struct/enum definitions aren't semicolon-terminated in D.
>>>
>>> Has anyone actually coded up the tweak to make Doxygen understand D?  Or are the D projects that use Doxygen built around Doxygen's limitations?
>>
>>
>>
>> Doxygen 1.3.7 only has basic support for D. It basically treats D as a variant of C++ with a little Java and C# mixed in (this allows it to recognize interfaces, for example).
>>
>> To get good results you need to combine it with a filtering program that translates most of the remaining D syntax quirks into something more C++-ish. The program is called dfilter.d and it was posted in this newsgroup a while back. Make sure you get the modified version for the new Doxygen, which was posted sometime at the end of the last year. I can repost it when I get home (don't have it here at work).
>>
>> Hauke
> 
> 
> I think I found your earlier message (I'm sure you'll correct me if I'm mistaken):  http://www.digitalmars.com/drn-bin/wwwnews?D/20989

Yep, that's the one. The filter is the same one that is also in the archive Ben Hinkle linked to, though.

http://www.sun-inet.or.jp/~yaneurao/dlang/lib/ddoc.zip

Hauke