# HG changeset patch # User Trass3r # Date 1284472010 -7200 # Node ID 78bf0fe43974d4626403be6b53e58e9bf6572a59 # Parent 95b3ed3cddd55c42fa37300312239586a20bb961# Parent 786ea1839396698db91c9af56e547eecc4404528 merge diff -r 95b3ed3cddd5 -r 78bf0fe43974 dmd/Scope.d --- a/dmd/Scope.d Tue Sep 14 15:25:44 2010 +0200 +++ b/dmd/Scope.d Tue Sep 14 15:46:50 2010 +0200 @@ -21,11 +21,11 @@ import dmd.Identifier; import dmd.Loc; import dmd.OutBuffer; -import dmd.DocComment; import dmd.DsymbolTable; import dmd.Global; import dmd.CSX; import dmd.Util; +import dmd.ddoc.DocComment; import core.memory; diff -r 95b3ed3cddd5 -r 78bf0fe43974 dmd/Section.d --- a/dmd/Section.d Tue Sep 14 15:25:44 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -module dmd.Section; - -import dmd.common; -import dmd.DocComment; -import dmd.Scope; -import dmd.Dsymbol; -import dmd.OutBuffer; - -class Section -{ - ubyte* name; - uint namelen; - - ubyte* body_; - uint bodylen; - - int nooutput; - - void write(DocComment dc, Scope sc, Dsymbol s, OutBuffer buf) - { - assert(false); - } -} \ No newline at end of file diff -r 95b3ed3cddd5 -r 78bf0fe43974 dmd/ddoc/DocComment.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmd/ddoc/DocComment.d Tue Sep 14 15:46:50 2010 +0200 @@ -0,0 +1,220 @@ +module dmd.ddoc.DocComment; + +import dmd.ddoc.Sections; +import dmd.Array; +import dmd.Macro; +import dmd.Escape; +import dmd.Scope; +import dmd.Dsymbol; +import dmd.OutBuffer; + +//! +class DocComment +{ + Sections sections; // Section*[] + + Section summary; + Section copyright; + Section macros; + Macro** pmacrotable; + Escape** pescapetable; + + this() + { + // TODO: memset(this, 0, sizeof(DocComment)); + } + + static DocComment parse(Scope sc, Dsymbol s, string comment) + { + unsigned idlen; + + //printf("parse(%s): '%s'\n", s.toChars(), comment); + if (sc.lastdc && isDitto(comment)) + return null; + + DocComment dc = new DocComment(); + if (!comment) + return dc; + + dc.parseSections(comment); + + foreach (Section s; dc.sections) + { + if (icmp("copyright", s.name, s.namelen) == 0) + { + dc.copyright = s; + } + if (icmp("macros", s.name, s.namelen) == 0) + { + dc.macros = s; + } + } + + sc.lastdc = dc; + return dc; + } + + static void parseMacros(Escape** pescapetable, Macro** pmacrotable, ubyte* m, uint mlen) + { + assert(false); + } + + static void parseEscapes(Escape** pescapetable, ubyte* textstart, uint textlen) + { + assert(false); + } + /***************************************** + * Parse next paragraph out of *pcomment. + * Update *pcomment to point past paragraph. + * Returns null if no more paragraphs. + * If paragraph ends in 'identifier:', + * then (*pcomment)[0 .. idlen] is the identifier. + */ + void parseSections(ubyte* comment) + { + ubyte*p; + ubyte*pstart; + ubyte*pend; + ubyte*idstart; + unsigned idlen; + + ubyte*name = null; + unsigned namelen = 0; + + //printf("parseSections('%s')\n", comment); + p = comment; + while (*p) + { + p = skipwhitespace(p); + pstart = p; + + /* Find end of section, which is ended by one of: + * 'identifier:' (but not inside a code section) + * '\0' + */ + idlen = 0; + int inCode = 0; + while (1) + { + // Check for start/end of a code section + if (*p == '-') + { + int numdash = 0; + while (*p == '-') + { + ++numdash; + p++; + } + // BUG: handle UTF PS and LS too + if (!*p || *p == '\r' || *p == '\n' && numdash >= 3) + inCode ^= 1; + } + + if (!inCode && isIdStart(p)) + { + ubyte*q = p + utfStride(p); + while (isIdTail(q)) + q += utfStride(q); + if (*q == ':') // identifier: ends it + { + idlen = q - p; + idstart = p; + for (pend = p; pend > pstart; pend--) + { + if (pend[-1] == '\n') + break; + } + p = q + 1; + break; + } + } + while (1) + { + if (!*p) + { pend = p; + goto L1; + } + if (*p == '\n') + { p++; + if (*p == '\n' && !summary && !namelen) + { + pend = p; + p++; + goto L1; + } + break; + } + p++; + } + p = skipwhitespace(p); + } + L1: + + if (namelen || pstart < pend) + { + Section *s; + if (icmp("Params", name, namelen) == 0) + s = new ParamSection(); + else if (icmp("Macros", name, namelen) == 0) + s = new MacroSection(); + else + s = new Section(); + s.name = name; + s.namelen = namelen; + s.body_ = pstart; + s.bodylen = pend - pstart; + s.nooutput = 0; + + //printf("Section: '%.*s' = '%.*s'\n", s.namelen, s.name, s.body_len, s.body); + + sections.push(s); + + if (!summary && !namelen) + summary = s; + } + + if (idlen) + { name = idstart; + namelen = idlen; + } + else + { name = null; + namelen = 0; + if (!*p) + break; + } + } + } + + void writeSections(Scope sc, Dsymbol s, OutBuffer buf) + { + //printf("DocComment.writeSections()\n"); + if (sections.dim) + { + buf.writestring("$(DDOC_SECTIONS \n"); + for (int i = 0; i < sections.dim; i++) + { + Section sec = cast(Section)sections.data[i]; + + if (sec.nooutput) + continue; + //printf("Section: '%.*s' = '%.*s'\n", sec.namelen, sec.name, sec.bodylen, sec.body); + if (sec.namelen || i) + sec.write(this, sc, s, buf); + else + { + buf.writestring("$(DDOC_SUMMARY "); + unsigned o = buf.offset; + buf.write(sec.body_, sec.bodylen); + highlightText(sc, s, buf, o); + buf.writestring(")\n"); + } + } + buf.writestring(")\n"); + } + else + { + buf.writestring("$(DDOC_BLANKLINE)\n"); + } + } +} \ No newline at end of file diff -r 95b3ed3cddd5 -r 78bf0fe43974 dmd/ddoc/Sections.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmd/ddoc/Sections.d Tue Sep 14 15:46:50 2010 +0200 @@ -0,0 +1,192 @@ +module dmd.ddoc.Sections; + +import dmd.common; +import dmd.ddoc.DocComment; +import dmd.Array; +import dmd.Scope; +import dmd.Dsymbol; +import dmd.OutBuffer; + +//! +alias Vector!Section Sections; + +//! +class Section +{ + string name; + string body_; + + int nooutput; + + void write(DocComment dc, Scope sc, Dsymbol s, OutBuffer buf) + { + if (namelen) + { + static string[] table = + { "AUTHORS", "BUGS", "COPYRIGHT", "DATE", + "DEPRECATED", "EXAMPLES", "HISTORY", "LICENSE", + "RETURNS", "SEE_ALSO", "STANDARDS", "THROWS", + "VERSION" }; + + for (int i = 0; i < table.length; i++) + { + if (icmp(table[i], name, namelen) == 0) + { + buf.printf("$(DDOC_%s ", table[i]); + goto L1; + } + } + + buf.writestring("$(DDOC_SECTION "); + // Replace _ characters with spaces + buf.writestring("$(DDOC_SECTION_H "); + size_t o = buf.offset; + for (size_t u = 0; u < namelen; u++) + { + char c = name[u]; + buf.writeByte((c == '_') ? ' ' : c); + } + escapeStrayParenthesis(buf, o, s.loc); + buf.writestring(":)\n"); + } + else + { + buf.writestring("$(DDOC_DESCRIPTION "); + } + L1: + unsigned o = buf.offset; + buf.write(body_, bodylen); + escapeStrayParenthesis(buf, o, s.loc); + highlightText(sc, s, buf, o); + buf.writestring(")\n"); + } +} + +//! +class ParamSection : Section +{ + override void write(DocComment dc, Scope sc, Dsymbol s, OutBuffer buf) + { + ubyte*p = body_; + unsigned len = bodylen; + ubyte*pend = p + len; + + ubyte*tempstart; + unsigned templen; + + ubyte*namestart; + unsigned namelen = 0; // !=0 if line continuation + + ubyte*textstart; + unsigned textlen; + + unsigned o; + Parameter *arg; + + buf.writestring("$(DDOC_PARAMS \n"); + while (p < pend) + { + // Skip to start of macro + while (1) + { + switch (*p) + { + case ' ': + case '\t': + p++; + continue; + + case '\n': + p++; + goto Lcont; + + default: + if (isIdStart(p)) + break; + if (namelen) + goto Ltext; // continuation of prev macro + goto Lskipline; + } + break; + } + tempstart = p; + + while (isIdTail(p)) + p += utfStride(p); + templen = p - tempstart; + + while (*p == ' ' || *p == '\t') + p++; + + if (*p != '=') + { if (namelen) + goto Ltext; // continuation of prev macro + goto Lskipline; + } + p++; + + if (namelen) + { // Output existing param + + L1: + //printf("param '%.*s' = '%.*s'\n", namelen, namestart, textlen, textstart); + HdrGenState hgs; + buf.writestring("$(DDOC_PARAM_ROW "); + buf.writestring("$(DDOC_PARAM_ID "); + o = buf.offset; + arg = isFunctionParameter(s, namestart, namelen); + if (arg && arg.type && arg.ident) + arg.type.toCBuffer(buf, arg.ident, &hgs); + else + buf.write(namestart, namelen); + escapeStrayParenthesis(buf, o, s.loc); + highlightCode(sc, s, buf, o); + buf.writestring(")\n"); + + buf.writestring("$(DDOC_PARAM_DESC "); + o = buf.offset; + buf.write(textstart, textlen); + escapeStrayParenthesis(buf, o, s.loc); + highlightText(sc, s, buf, o); + buf.writestring(")"); + buf.writestring(")\n"); + namelen = 0; + if (p >= pend) + break; + } + + namestart = tempstart; + namelen = templen; + + while (*p == ' ' || *p == '\t') + p++; + textstart = p; + + Ltext: + while (*p != '\n') + p++; + textlen = p - textstart; + p++; + + Lcont: + continue; + + Lskipline: + // Ignore this line + while (*p++ != '\n') {} + } + if (namelen) + goto L1; // write out last one + buf.writestring(")\n"); + } +} + +//! +class MacroSection : Section +{ + override void write(DocComment dc, Scope sc, Dsymbol s, OutBuffer buf) + { + // writef("MacroSection.write()\n"); + DocComment.parseMacros(dc.pescapetable, dc.pmacrotable, body_, bodylen); + } +} \ No newline at end of file