view dmd/ddoc/DocComment.d @ 152:4092a614a9f3

moved Escape and Macro to ddoc folder
author Trass3r
date Wed, 15 Sep 2010 03:00:30 +0200
parents 786ea1839396
children 560eaedcb7a2
line wrap: on
line source

module dmd.ddoc.DocComment;

import dmd.ddoc.Escape;
import dmd.ddoc.Macro;
import dmd.ddoc.Sections;
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)
	{
		unsigned 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)
	{
		assert(false);
	}
	
	/**************************************
	 * 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)
	{
		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(string 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");
		}
	}
}