Mercurial > projects > ddmd
view dmd/ddoc/DocComment.d @ 153:560eaedcb7a2
added lots of ddoc code, still needs much care
added helpers functions in ddoc.Util
author | trass3r |
---|---|
date | Wed, 15 Sep 2010 04:18:46 +0200 |
parents | 4092a614a9f3 |
children |
line wrap: on
line source
module dmd.ddoc.DocComment; import dmd.ddoc.Escape; import dmd.ddoc.Macro; import dmd.ddoc.Sections; import dmd.ddoc.Util; import dmd.Array; 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) { uint idlen; // writef("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; } /************************************************ * Parse macros out of Macros: section. * Macros are of the form: * name1 = value1 * * name2 = value2 */ static void parseMacros(Escape** pescapetable, Macro** pmacrotable, ubyte* m, uint mlen) {/+ unsigned char *p = m; unsigned len = mlen; unsigned char *pend = p + len; unsigned char *tempstart; unsigned templen; unsigned char *namestart; unsigned namelen = 0; // !=0 if line continuation unsigned char *textstart; unsigned textlen; while (p < pend) { // Skip to start of macro while (1) { if (p >= pend) goto Ldone; 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 (1) { if (p >= pend) goto Ldone; if (!isIdTail(p)) break; p += utfStride(p); } templen = p - tempstart; while (1) { if (p >= pend) goto Ldone; if (!(*p == ' ' || *p == '\t')) break; p++; } if (*p != '=') { if (namelen) goto Ltext; // continuation of prev macro goto Lskipline; } p++; if (p >= pend) goto Ldone; if (namelen) { // Output existing macro L1: //printf("macro '%.*s' = '%.*s'\n", namelen, namestart, textlen, textstart); if (icmp("ESCAPES", namestart, namelen) == 0) parseEscapes(pescapetable, textstart, textlen); else Macro.define(pmacrotable, namestart, namelen, textstart, textlen); namelen = 0; if (p >= pend) break; } namestart = tempstart; namelen = templen; while (p < pend && (*p == ' ' || *p == '\t')) p++; textstart = p; Ltext: while (p < pend && *p != '\n') p++; textlen = p - textstart; // Remove trailing \r if there is one if (p > m && p[-1] == '\r') textlen--; p++; //printf("p = %p, pend = %p\n", p, pend); Lcont: continue; Lskipline: // Ignore this line while (p < pend && *p++ != '\n') {} } Ldone: if (namelen) goto L1; // write out last one +/} /************************************** * Parse escapes of the form: * /c/string/ * where c is a single character. * Multiple escapes can be separated * by whitespace and/or commas. */ static void parseEscapes(Escape** pescapetable, ubyte* textstart, uint textlen) {/+ Escape *escapetable = *pescapetable; if (!escapetable) { escapetable = new Escape; *pescapetable = escapetable; } unsigned char *p = textstart; unsigned char *pend = p + textlen; while (1) { while (1) { if (p + 4 >= pend) return; if (!(*p == ' ' || *p == '\t' || *p == '\n' || *p == ',')) break; p++; } if (p[0] != '/' || p[2] != '/') return; unsigned char c = p[1]; p += 3; unsigned char *start = p; while (1) { if (p >= pend) return; if (*p == '/') break; p++; } size_t len = p - start; char *s = (char *)memcpy(mem.malloc(len + 1), start, len); s[len] = 0; escapetable.strings[c] = s; //printf("%c = '%s'\n", c, s); p++; } +/} /***************************************** * 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(string comment) { ubyte*p; ubyte*pstart; ubyte*pend; ubyte*idstart; uint idlen; ubyte*name = null; size_t 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 "); uint 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"); } } }