Skip to content

Commit

Permalink
Fix Issue 11511 - DDoc - C variadic parameters cannot be properly doc…
Browse files Browse the repository at this point in the history
…umented.
  • Loading branch information
AndrejMitrovic committed Apr 27, 2014
1 parent c5ebee1 commit a01afe0
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 7 deletions.
45 changes: 38 additions & 7 deletions src/doc.c
Expand Up @@ -116,10 +116,18 @@ Parameter *isFunctionParameter(Dsymbol *s, const utf8_t *p, size_t len);
TemplateParameter *isTemplateParameter(Dsymbol *s, const utf8_t *p, size_t len);

int isIdStart(const utf8_t *p);
bool isCVariadicArg(const utf8_t *p, size_t len);
int isIdTail(const utf8_t *p);
int isIndentWS(const utf8_t *p);
int utfStride(const utf8_t *p);

// Workaround for missing Parameter instance for variadic params. (it's unnecessary to instantiate one).
bool isCVariadicParameter(Dsymbol *s, const utf8_t *p, size_t len)
{
TypeFunction *tf = isTypeFunction(s);
return tf && tf->varargs == 1 && cmp("...", p, len) == 0;
}

static const char ddoc_default[] = "\
DDOC = <html><head>\n\
<META http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n\
Expand Down Expand Up @@ -1598,7 +1606,7 @@ void ParamSection::write(DocComment *dc, Scope *sc, Dsymbol *s, OutBuffer *buf)
goto Lcont;

default:
if (isIdStart(p))
if (isIdStart(p) || isCVariadicArg(p, pend - p))
break;
if (namelen)
goto Ltext; // continuation of prev macro
Expand All @@ -1610,13 +1618,17 @@ void ParamSection::write(DocComment *dc, Scope *sc, Dsymbol *s, OutBuffer *buf)

while (isIdTail(p))
p += utfStride(p);
if (isCVariadicArg(p, pend - p))
p += 3;

templen = p - tempstart;

while (*p == ' ' || *p == '\t')
p++;

if (*p != '=')
{ if (namelen)
{
if (namelen)
goto Ltext; // continuation of prev macro
goto Lskipline;
}
Expand All @@ -1633,7 +1645,12 @@ void ParamSection::write(DocComment *dc, Scope *sc, Dsymbol *s, OutBuffer *buf)
buf->writestring("$(DDOC_PARAM_ID ");
o = buf->offset;
arg = isFunctionParameter(s, namestart, namelen);
if (arg && arg->type && arg->ident)
bool isCVariadic = isCVariadicParameter(s, namestart, namelen);
if (isCVariadic)
{
buf->writestring("...");
}
else if (arg && arg->type && arg->ident)
{
arg->type->toCBuffer(buf, arg->ident, &hgs);
}
Expand Down Expand Up @@ -1694,7 +1711,7 @@ void ParamSection::write(DocComment *dc, Scope *sc, Dsymbol *s, OutBuffer *buf)
TypeFunction *tf = isTypeFunction(s);
if (tf)
{
size_t pcount = tf->parameters ? tf->parameters->dim : 0;
size_t pcount = (tf->parameters ? tf->parameters->dim : 0) + (int)(tf->varargs == 1);
if (pcount != paramcount)
{
warning(s->loc, "Ddoc: parameter count mismatch");
Expand Down Expand Up @@ -2429,7 +2446,9 @@ void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset)
}
else
{
if (f && isFunctionParameter(f, (utf8_t *)buf->data + i, j - i))
utf8_t *start = (utf8_t *)buf->data + i;
size_t end = j - i;
if (f && (isFunctionParameter(f, start, end) || isCVariadicParameter(f, start, end)))
{
//printf("highlighting arg '%s', i = %d, j = %d\n", arg->ident->toChars(), i, j);
i = buf->bracket(i, "$(DDOC_PARAM ", j, ")") - 1;
Expand Down Expand Up @@ -2490,7 +2509,9 @@ void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset, bool an
}
else if (f)
{
if (isFunctionParameter(f, (utf8_t *)buf->data + i, j - i))
utf8_t *start = (utf8_t *)buf->data + i;
size_t end = j - i;
if (isFunctionParameter(f, start, end) || isCVariadicParameter(f, start, end))
{
//printf("highlighting arg '%s', i = %d, j = %d\n", arg->ident->toChars(), i, j);
i = buf->bracket(i, "$(DDOC_PARAM ", j, ")") - 1;
Expand Down Expand Up @@ -2555,7 +2576,8 @@ void highlightCode2(Scope *sc, Dsymbol *s, OutBuffer *buf, size_t offset)
}
else if (f)
{
if (isFunctionParameter(f, tok.ptr, lex.p - tok.ptr))
size_t end = lex.p - tok.ptr;
if (isFunctionParameter(f, tok.ptr, end) || isCVariadicParameter(f, tok.ptr, end))
{
//printf("highlighting arg '%s', i = %d, j = %d\n", arg->ident->toChars(), i, j);
highlight = "$(D_PARAM ";
Expand Down Expand Up @@ -2628,6 +2650,15 @@ const char *Escape::escapeChar(unsigned c)
#endif
}

/****************************************
* Determine if p points to the start of a "..." parameter identifier.
*/

bool isCVariadicArg(const utf8_t *p, size_t len)
{
return len >= 3 && cmp("...", p, 3) == 0;
}

/****************************************
* Determine if p points to the start of an identifier.
*/
Expand Down
20 changes: 20 additions & 0 deletions test/compilable/ddoc11511.d
@@ -0,0 +1,20 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -w -D -Dd${RESULTS_DIR}/compilable -o-
// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh 11511
module ddoc11511;

/**
Params:
abcd = none1
bcdef = none23
... = doo
*/
void foo(int abcd, int bcdef, ...);

/**
Params:
abcd = none1
bcdef = none23
arr = doo
*/
void foo(int abcd, int bcdef, int[] arr...);
34 changes: 34 additions & 0 deletions test/compilable/extra-files/ddoc11511.html
@@ -0,0 +1,34 @@
<html><head>
<META http-equiv="content-type" content="text/html; charset=utf-8">
<title>ddoc11511</title>
</head><body>
<h1>ddoc11511</h1>
<br><br>
<dl><dt><big><a name="foo"></a>void <u>foo</u>(int <i>abcd</i>, int <i>bcdef</i>, ...);
</big></dt>
<dd><b>Params:</b><br>
<table><tr><td>int <i>abcd</i></td>
<td>none1</td></tr>
<tr><td>int <i>bcdef</i></td>
<td>none23</td></tr>
<tr><td>...</td>
<td>doo</td></tr>
</table><br>

</dd>
<dt><big><a name="foo"></a>void <u>foo</u>(int <i>abcd</i>, int <i>bcdef</i>, int[] <i>arr</i>...);
</big></dt>
<dd><b>Params:</b><br>
<table><tr><td>int <i>abcd</i></td>
<td>none1</td></tr>
<tr><td>int <i>bcdef</i></td>
<td>none23</td></tr>
<tr><td>int[] <i>arr</i></td>
<td>doo</td></tr>
</table><br>

</dd>
</dl>

<hr><small>Page generated by <a href="http://dlang.org/ddoc.html">Ddoc</a>. </small>
</body></html>

0 comments on commit a01afe0

Please sign in to comment.