From 6b29c4e55009771545305fe3ec3ba92e8d0ba38e Mon Sep 17 00:00:00 2001 From: Matthew White Date: Sat, 22 Jul 2017 21:15:02 +0200 Subject: Fix/New: add variadic function args '...' support to @link * src/util.h (substitute): add skip_seq to function declaration * src/util.cpp (substitute): implement skip_seq to keep unchanged a given number of sequential chars otherwise targeted for substitution * src/util.cpp (resolveRef): call substitute() with skip_seq set to 3 to keep each '...' sequence of chars unchanged For instance, the command {@link fun(int,...)} now keeps each '...' sequence of chars unchanged to reference fun(int,...). Before this patch, each '.' was substituted into '::' by resolveRef() calling substitute(), producing a weird reference to fun(int,::::::). --- src/util.cpp | 34 ++++++++++++++++++++++++++++++---- src/util.h | 2 +- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index e44f825..8fcd8e3 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -4594,7 +4594,7 @@ bool resolveRef(/* in */ const char *scName, QCString fullName = substitute(tsName,"#","::"); if (fullName.find("anonymous_namespace{")==-1) { - fullName = removeRedundantWhiteSpace(substitute(fullName,".","::")); + fullName = removeRedundantWhiteSpace(substitute(fullName,".","::",3)); } else { @@ -5186,8 +5186,11 @@ QCString showFileDefMatches(const FileNameDict *fnDict,const char *n) //---------------------------------------------------------------------- -/// substitute all occurrences of \a src in \a s by \a dst -QCString substitute(const QCString &s,const QCString &src,const QCString &dst) +/// substitute all occurrences of \a src in \a s by \a dst, but skip +/// each consecutive sequence of \a src where the number consecutive +/// \a src matches \a skip_seq; if \a skip_seq is negative, skip any +/// number of consecutive \a src +QCString substitute(const QCString &s,const QCString &src,const QCString &dst,int skip_seq) { if (s.isEmpty() || src.isEmpty()) return s; const char *p, *q; @@ -5208,13 +5211,36 @@ QCString substitute(const QCString &s,const QCString &src,const QCString &dst) char *r; for (r=result.rawData(), p=s; (q=strstr(p,src))!=0; p=q+srcLen) { - int l = (int)(q-p); + // search a consecutive sequence of src + int seq = 0, skip = 0; + if (skip_seq) + { + for (const char *n=q+srcLen; qstrncmp(n,src,srcLen)==0; seq=1+skip, n+=srcLen) + ++skip; // number of consecutive src after the current one + + // verify the allowed number of consecutive src to skip + if (skip_seq > 0 && skip_seq != seq) + seq = skip = 0; + } + + // skip a consecutive sequence of src when necessary + int l = (int)((q + seq * srcLen)-p); memcpy(r,p,l); r+=l; + + if (skip) + { + // skip only the consecutive src found after the current one + q += skip * srcLen; + // the next loop will skip the current src, aka (p=q+srcLen) + continue; + } + if (dst) memcpy(r,dst,dstLen); r+=dstLen; } qstrcpy(r,p); + result.resize(strlen(result.data())+1); //printf("substitute(%s,%s,%s)->%s\n",s,src,dst,result.data()); return result; } diff --git a/src/util.h b/src/util.h index af8a3b4..9b98d83 100644 --- a/src/util.h +++ b/src/util.h @@ -193,7 +193,7 @@ void mergeArguments(ArgumentList *,ArgumentList *,bool forceNameOverwrite=FALSE) QCString substituteClassNames(const QCString &s); -QCString substitute(const QCString &s,const QCString &src,const QCString &dst); +QCString substitute(const QCString &s,const QCString &src,const QCString &dst,int skip_seq = 0); QCString clearBlock(const char *s,const char *begin,const char *end); -- cgit v0.12 From 037f465e934ce122c8412b55548a153ad517aba0 Mon Sep 17 00:00:00 2001 From: Matthew White Date: Mon, 24 Jul 2017 06:04:25 +0200 Subject: Fix/New: add variadic function args '...' support to @ref * src/doctokenizer.l: add VARARGS, aka variadic function args '...' * src/util.cpp (linkToText): call substitute() with skip_seq set to 3 to keep each '...' sequence of chars unchanged For instance, the command '@ref fun(int,...)' now is able to parse each '...' sequence of chars correctly to reference fun(int,...). Before this patch, the '...' part was skipped. Also, linkToText() is fixed to not substitute '...' with '::::::' in the text representation of the link. --- src/doctokenizer.l | 3 ++- src/util.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/doctokenizer.l b/src/doctokenizer.l index 7545cba..90a8c55 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -360,8 +360,9 @@ SPCMD3 {CMD}form#[0-9]+ SPCMD4 {CMD}"::" INOUT "inout"|"in"|"out"|("in"{BLANK}*","{BLANK}*"out")|("out"{BLANK}*","{BLANK}*"in") PARAMIO {CMD}param{BLANK}*"["{BLANK}*{INOUT}{BLANK}*"]" +VARARGS "..." TEMPCHAR [a-z_A-Z0-9.,: \t\*\&\(\)\[\]] -FUNCCHAR [a-z_A-Z0-9,:\<\> \t\^\*\&\[\]] +FUNCCHAR [a-z_A-Z0-9,:\<\> \t\^\*\&\[\]]|{VARARGS} FUNCPART {FUNCCHAR}*("("{FUNCCHAR}*")"{FUNCCHAR}*)? SCOPESEP "::"|"#"|"." TEMPLPART "<"{TEMPCHAR}*">" diff --git a/src/util.cpp b/src/util.cpp index 8fcd8e3..02cb27b 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -4767,7 +4767,7 @@ QCString linkToText(SrcLangExt lang,const char *link,bool isFileName) // replace # by :: result=substitute(result,"#","::"); // replace . by :: - if (!isFileName && result.find('<')==-1) result=substitute(result,".","::"); + if (!isFileName && result.find('<')==-1) result=substitute(result,".","::",3); // strip leading :: prefix if present if (result.at(0)==':' && result.at(1)==':') { -- cgit v0.12 From fce142b4282d80f16fff53ba1cbd2572119b17ef Mon Sep 17 00:00:00 2001 From: Matthew White Date: Mon, 24 Jul 2017 07:28:12 +0200 Subject: Add variadic function arguments '...' regression tests * testing/067_link_varargs.cpp: new file, @link regression test for variadic function arguments '...' * testing/067/067__link__varargs_8cpp.xml: new file, expected @link regression test result for variadic function arguments '...' * testing/068_ref_varargs.cpp: new file, @ref regression test for variadic function arguments '...' * testing/068/068__ref__varargs_8cpp.xml: new file, expected @ref regression test result for variadic function arguments '...' --- testing/067/067__link__varargs_8cpp.xml | 54 +++++++++++++++++++++++++++++++++ testing/067_link_varargs.cpp | 20 ++++++++++++ testing/068/068__ref__varargs_8cpp.xml | 54 +++++++++++++++++++++++++++++++++ testing/068_ref_varargs.cpp | 20 ++++++++++++ 4 files changed, 148 insertions(+) create mode 100644 testing/067/067__link__varargs_8cpp.xml create mode 100644 testing/067_link_varargs.cpp create mode 100644 testing/068/068__ref__varargs_8cpp.xml create mode 100644 testing/068_ref_varargs.cpp diff --git a/testing/067/067__link__varargs_8cpp.xml b/testing/067/067__link__varargs_8cpp.xml new file mode 100644 index 0000000..76eb543 --- /dev/null +++ b/testing/067/067__link__varargs_8cpp.xml @@ -0,0 +1,54 @@ + + + + 067_link_varargs.cpp + Test + + + void + void func + (int p) + func + + int + p + + + + + A function + + + + + + + void + void func + (int p,...) + func + + int + p + + + ... + + + + + Overloaded function taking variadic arguments + + + + + + + + + + See the function for more info. See the test class. + + + + diff --git a/testing/067_link_varargs.cpp b/testing/067_link_varargs.cpp new file mode 100644 index 0000000..8cf25a2 --- /dev/null +++ b/testing/067_link_varargs.cpp @@ -0,0 +1,20 @@ +// objective: test \link command with function variadic arguments '...' +// check: 067__link__varargs_8cpp.xml + +/** \file + * See \link func(int,...) the function\endlink for more info. + * See the \link Test test\endlink class. + */ + +/** A function + */ +void func(int p); + +/** Overloaded function taking variadic arguments + */ +void func(int p, ...); + +/** A test */ +class Test +{ +}; diff --git a/testing/068/068__ref__varargs_8cpp.xml b/testing/068/068__ref__varargs_8cpp.xml new file mode 100644 index 0000000..8e0dc00 --- /dev/null +++ b/testing/068/068__ref__varargs_8cpp.xml @@ -0,0 +1,54 @@ + + + + 068_ref_varargs.cpp + Test + + + void + void func + (int p) + func + + int + p + + + + + A function + + + + + + + void + void func + (int p,...) + func + + int + p + + + ... + + + + + Overloaded function taking variadic arguments + + + + + + + + + + See the function for more info. See the test class. + + + + diff --git a/testing/068_ref_varargs.cpp b/testing/068_ref_varargs.cpp new file mode 100644 index 0000000..c85daa2 --- /dev/null +++ b/testing/068_ref_varargs.cpp @@ -0,0 +1,20 @@ +// objective: test \ref command with function variadic arguments '...' +// check: 068__ref__varargs_8cpp.xml + +/** \file + * See \ref func(int,...) "the function" for more info. + * See the \ref Test "test" class. + */ + +/** A function + */ +void func(int p); + +/** Overloaded function taking variadic arguments + */ +void func(int p, ...); + +/** A test */ +class Test +{ +}; -- cgit v0.12 From 818f0458205a2965f0a676265e2454450a4c3455 Mon Sep 17 00:00:00 2001 From: Matthew White Date: Mon, 24 Jul 2017 10:02:35 +0200 Subject: Add variadic template function regression tests * testing/069_link_variadic_template.cpp: new file, @link regression test for variadic template function * testing/069/069__link__variadic__template_8cpp.xml: new file, expected @link regression test result for variadic template function * testing/070_ref_variadic_template.cpp: new file, @ref regression test for variadic template function * testing/070/070__ref__variadic__template_8cpp.xml: new file, expected @ref regression test result for variadic template function At the time of writing, the part between <> is totally ignored: func(Args... args) is interpreted as func(Args... args). Beware that a function parameter with either a & or * operator, e.g. 'const Args&... args', requires @link and @ref to use such parameter as verbatim, i.e. {@link func(const Args&... args)}. At the time of writing, the form {@link func(const Args&...)} will fail, unless the function parameter was declared just as 'const Args&...'. --- testing/069/069__link__variadic__template_8cpp.xml | 309 +++++++++++++++++++++ testing/069_link_variadic_template.cpp | 95 +++++++ testing/070/070__ref__variadic__template_8cpp.xml | 309 +++++++++++++++++++++ testing/070_ref_variadic_template.cpp | 95 +++++++ 4 files changed, 808 insertions(+) create mode 100644 testing/069/069__link__variadic__template_8cpp.xml create mode 100644 testing/069_link_variadic_template.cpp create mode 100644 testing/070/070__ref__variadic__template_8cpp.xml create mode 100644 testing/070_ref_variadic_template.cpp diff --git a/testing/069/069__link__variadic__template_8cpp.xml b/testing/069/069__link__variadic__template_8cpp.xml new file mode 100644 index 0000000..c93a732 --- /dev/null +++ b/testing/069/069__link__variadic__template_8cpp.xml @@ -0,0 +1,309 @@ + + + + 069_link_variadic_template.cpp + Test + + + void + void func + (int p) + func + + int + p + + + + + A function + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, Args &... args) + func + + int + p + + + Args &... + args + + + + + A variadic template function overload + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, Args &&... args) + func + + int + p + + + Args &&... + args + + + + + A variadic template function overload + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, const Args &... args) + func + + int + p + + + const Args &... + args + + + + + A variadic template function overload + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, const Args &&... args) + func + + int + p + + + const Args &&... + args + + + + + A variadic template function overload + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, Args *... args) + func + + int + p + + + Args *... + args + + + + + A variadic template function overload + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, Args **... args) + func + + int + p + + + Args **... + args + + + + + A variadic template function overload + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, const Args *... args) + func + + int + p + + + const Args *... + args + + + + + A variadic template function overload + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, const Args **... args) + func + + int + p + + + const Args **... + args + + + + + A variadic template function overload + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, Args... args) + func + + int + p + + + Args... + args + + + + + A variadic template function overload + + + + + + + + + + + + + + At the time of writing, the part between <> is totally ignored: func<Args...>(Args... args) is interpreted as func(Args... args). + Beware that a function parameter with either a & or * operator, e.g. 'const Args&... args', requires \link and \ref to specify such parameter as verbatim, i.e. 'const Args&... args'. At the time of writing, the form func(const Args&...) will fail, unless the function parameter was declared just as 'const Args&...'. + + + + + + variadic template method + + Links to the variadic template function overloads: First overloadSecond overloadThird overloadFourth overloadFifth overloadSixth overloadSeventh overloadEighth overloadNinth overload +The followings are interpreted the same: without template argumentwith template argument +See the test class. + + + + diff --git a/testing/069_link_variadic_template.cpp b/testing/069_link_variadic_template.cpp new file mode 100644 index 0000000..89ab57c --- /dev/null +++ b/testing/069_link_variadic_template.cpp @@ -0,0 +1,95 @@ +// objective: test \link command with a variadic template function +// check: 069__link__variadic__template_8cpp.xml + +/** \file + * + * @attention + * @parblock + * At the time of writing, the part between \<\> is totally ignored: + * %func(Args... args) is interpreted as %func(Args... args). + * + * Beware that a function parameter with either a \& or \* operator, + * e.g. 'const Args&... args', requires \\link and \\ref to specify + * such parameter as verbatim, i.e. 'const Args&... args'. At the + * time of writing, the form %func(const Args&...) will fail, unless + * the function parameter was declared just as 'const Args&...'. + * @endparblock + * + * \link Test::func(int,Args...)const variadic template method\endlink + * + * Links to the variadic template function overloads: + * @li \link func(int,Args&... args) First overload\endlink + * @li \link func(int,Args&&... args) Second overload\endlink + * @li \link func(int,const Args&... args) Third overload\endlink + * @li \link func(int,const Args&&... args) Fourth overload\endlink + * @li \link func(int,Args*... args) Fifth overload\endlink + * @li \link func(int,Args**... args) Sixth overload\endlink + * @li \link func(int,const Args*... args) Seventh overload\endlink + * @li \link func(int,const Args**... args) Eighth overload\endlink + * @li \link func(int,Args...) Ninth overload\endlink + * + * The followings are interpreted the same: + * @li \link func(int,const Args&... args) without template argument\endlink + * @li \link func(int,const Args&... args) with template argument\endlink + * + * See the \link Test test\endlink class. + */ + +/** A function + */ +void func(int p); + +/** A variadic template function overload + */ +template +void func(int p, Args&... args); + +/** A variadic template function overload + */ +template +void func(int p, Args&&... args); + +/** A variadic template function overload + */ +template +void func(int p, const Args&... args); + +/** A variadic template function overload + */ +template +void func(int p, const Args&&... args); + +/** A variadic template function overload + */ +template +void func(int p, Args*... args); + +/** A variadic template function overload + */ +template +void func(int p, Args**... args); + +/** A variadic template function overload + */ +template +void func(int p, const Args*... args); + +/** A variadic template function overload + */ +template +void func(int p, const Args**... args); + +/** A variadic template function overload + */ +template +void func(int p, Args... args); + +/** A test */ +class Test +{ + public: + /** A variadic template method + */ + template + void func(int p, Args... args) const; +}; diff --git a/testing/070/070__ref__variadic__template_8cpp.xml b/testing/070/070__ref__variadic__template_8cpp.xml new file mode 100644 index 0000000..0f581e5 --- /dev/null +++ b/testing/070/070__ref__variadic__template_8cpp.xml @@ -0,0 +1,309 @@ + + + + 070_ref_variadic_template.cpp + Test + + + void + void func + (int p) + func + + int + p + + + + + A function + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, Args &... args) + func + + int + p + + + Args &... + args + + + + + A variadic template function overload + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, Args &&... args) + func + + int + p + + + Args &&... + args + + + + + A variadic template function overload + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, const Args &... args) + func + + int + p + + + const Args &... + args + + + + + A variadic template function overload + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, const Args &&... args) + func + + int + p + + + const Args &&... + args + + + + + A variadic template function overload + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, Args *... args) + func + + int + p + + + Args *... + args + + + + + A variadic template function overload + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, Args **... args) + func + + int + p + + + Args **... + args + + + + + A variadic template function overload + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, const Args *... args) + func + + int + p + + + const Args *... + args + + + + + A variadic template function overload + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, const Args **... args) + func + + int + p + + + const Args **... + args + + + + + A variadic template function overload + + + + + + + + + typename... + Args + Args + + + void + void func + (int p, Args... args) + func + + int + p + + + Args... + args + + + + + A variadic template function overload + + + + + + + + + + + + + + At the time of writing, the part between <> is totally ignored: func<Args...>(Args... args) is interpreted as func(Args... args). + Beware that a function parameter with either a & or * operator, e.g. 'const Args&... args', requires \link and \ref to specify such parameter as verbatim, i.e. 'const Args&... args'. At the time of writing, the form func(const Args&...) will fail, unless the function parameter was declared just as 'const Args&...'. + + + + + + variadic template method + + References to the variadic template function overloads: First overloadSecond overloadThird overloadFourth overloadFifth overloadSixth overloadSeventh overloadEighth overloadNinth overload +The followings are interpreted the same: without template argumentwith template argument +See the test class. + + + + diff --git a/testing/070_ref_variadic_template.cpp b/testing/070_ref_variadic_template.cpp new file mode 100644 index 0000000..376cebe --- /dev/null +++ b/testing/070_ref_variadic_template.cpp @@ -0,0 +1,95 @@ +// objective: test \ref command with a variadic template function +// check: 070__ref__variadic__template_8cpp.xml + +/** \file + * + * @attention + * @parblock + * At the time of writing, the part between \<\> is totally ignored: + * %func(Args... args) is interpreted as %func(Args... args). + * + * Beware that a function parameter with either a \& or \* operator, + * e.g. 'const Args&... args', requires \\link and \\ref to specify + * such parameter as verbatim, i.e. 'const Args&... args'. At the + * time of writing, the form %func(const Args&...) will fail, unless + * the function parameter was declared just as 'const Args&...'. + * @endparblock + * + * \ref Test::func(int,Args...)const "variadic template method" + * + * References to the variadic template function overloads: + * @li \ref func(int,Args&... args) "First overload" + * @li \ref func(int,Args&&... args) "Second overload" + * @li \ref func(int,const Args&... args) "Third overload" + * @li \ref func(int,const Args&&... args) "Fourth overload" + * @li \ref func(int,Args*... args) "Fifth overload" + * @li \ref func(int,Args**... args) "Sixth overload" + * @li \ref func(int,const Args*... args) "Seventh overload" + * @li \ref func(int,const Args**... args) "Eighth overload" + * @li \ref func(int,Args...) "Ninth overload" + * + * The followings are interpreted the same: + * @li \ref func(int,const Args&... args) "without template argument" + * @li \ref func(int,const Args&... args) "with template argument" + * + * See the \ref Test "test" class. + */ + +/** A function + */ +void func(int p); + +/** A variadic template function overload + */ +template +void func(int p, Args&... args); + +/** A variadic template function overload + */ +template +void func(int p, Args&&... args); + +/** A variadic template function overload + */ +template +void func(int p, const Args&... args); + +/** A variadic template function overload + */ +template +void func(int p, const Args&&... args); + +/** A variadic template function overload + */ +template +void func(int p, Args*... args); + +/** A variadic template function overload + */ +template +void func(int p, Args**... args); + +/** A variadic template function overload + */ +template +void func(int p, const Args*... args); + +/** A variadic template function overload + */ +template +void func(int p, const Args**... args); + +/** A variadic template function overload + */ +template +void func(int p, Args... args); + +/** A test */ +class Test +{ + public: + /** A variadic template method + */ + template + void func(int p, Args... args) const; +}; -- cgit v0.12 From dd88186b18613388902e4921e5203375458783b6 Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Thu, 28 Dec 2017 10:01:43 +0100 Subject: Add variadic arguments support to @link and @ref, aka '...' arguments, fixes --- src/util.cpp | 35 +++++++++++++++++++++++++++++++++++ src/util.h | 3 ++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/util.cpp b/src/util.cpp index 6cc1fd3..7f87e19 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -5192,6 +5192,41 @@ QCString showFileDefMatches(const FileNameDict *fnDict,const char *n) //---------------------------------------------------------------------- +/// substitute all occurrences of \a src in \a s by \a dst +QCString substitute(const QCString &s,const QCString &src,const QCString &dst) +{ + if (s.isEmpty() || src.isEmpty()) return s; + const char *p, *q; + int srcLen = src.length(); + int dstLen = dst.length(); + int resLen; + if (srcLen!=dstLen) + { + int count; + for (count=0, p=s.data(); (q=strstr(p,src))!=0; p=q+srcLen) count++; + resLen = s.length()+count*(dstLen-srcLen); + } + else // result has same size as s + { + resLen = s.length(); + } + QCString result(resLen+1); + char *r; + for (r=result.rawData(), p=s; (q=strstr(p,src))!=0; p=q+srcLen) + { + int l = (int)(q-p); + memcpy(r,p,l); + r+=l; + + if (dst) memcpy(r,dst,dstLen); + r+=dstLen; + } + qstrcpy(r,p); + //printf("substitute(%s,%s,%s)->%s\n",s,src,dst,result.data()); + return result; +} + + /// substitute all occurrences of \a src in \a s by \a dst, but skip /// each consecutive sequence of \a src where the number consecutive /// \a src matches \a skip_seq; if \a skip_seq is negative, skip any diff --git a/src/util.h b/src/util.h index 066e072..e3853b5 100644 --- a/src/util.h +++ b/src/util.h @@ -193,7 +193,8 @@ void mergeArguments(ArgumentList *,ArgumentList *,bool forceNameOverwrite=FALSE) QCString substituteClassNames(const QCString &s); -QCString substitute(const QCString &s,const QCString &src,const QCString &dst,int skip_seq = 0); +QCString substitute(const QCString &s,const QCString &src,const QCString &dst); +QCString substitute(const QCString &s,const QCString &src,const QCString &dst,int skip_seq); QCString clearBlock(const char *s,const char *begin,const char *end); -- cgit v0.12