25#include <unordered_set>
80#define ENABLE_TRACINGSUPPORT 0
82#if defined(__APPLE__) && ENABLE_TRACINGSUPPORT
94#define REL_PATH_TO_ROOT "../../"
96static const char *
hex =
"0123456789ABCDEF";
117 if (str.
empty())
return result;
120 auto startsWithColon = [](
const std::string &del)
122 for (
size_t i=0;i<del.size();i++)
124 if (del[i]==
'@')
return false;
125 else if (del[i]==
':')
return true;
131 auto endsWithColon = [](
const std::string &del)
133 for (
int i=
static_cast<int>(del.size())-1;i>=0;i--)
135 if (del[i]==
'@')
return false;
136 else if (del[i]==
':')
return true;
141 static const reg::Ex re(R
"([\s:]*@\d+[\s:]*)");
142 std::string s = str.str();
146 size_t sl=s.length();
147 bool needsSeparator=
false;
148 for ( ; iter!=
end ; ++iter)
150 const auto &match = *iter;
151 size_t i = match.position();
154 if (needsSeparator) result+=
"::";
155 needsSeparator=
false;
156 result+=s.substr(p,i-p);
158 std::string delim = match.str();
159 needsSeparator = needsSeparator || (startsWithColon(delim) && endsWithColon(delim));
160 p = match.position()+match.length();
164 if (needsSeparator) result+=
"::";
173 if (s.
empty())
return s;
174 static const reg::Ex marker(R
"(@\d+)");
176 !replacement.empty() ? replacement.data() : "__anonymous__");
187 int sl =
static_cast<int>(s.
length());
195 if (!newScope.
empty()) newScope+=
"::";
196 newScope+=s.
mid(i,l);
201 if (!newScope.
empty()) newScope+=
"::";
202 newScope+=s.
right(sl-i);
218 result = path.
mid(4);
234 for (
const auto &s : l)
237 if (
prefix.length() > length &&
244 if (length>0)
return potential;
267 AUTO_TRACE(
"context='{}' qualifiedName='{}'",context?context->
name():
"",qualifiedName);
269 if (qualifiedName.
empty())
276 if (typedefContext) *typedefContext=context;
284 size_t scopeIndex = qualifiedName.
rfind(
"::");
288 resName=qualifiedName.
mid(scopeIndex+2);
296 while (mContext && md==
nullptr)
303 DString resScopeName = qualifiedName.
left(scopeIndex);
310 DString qualScopePart = resScopeName.
mid(is,l);
312 if (!tmp.
empty()) qualScopePart=tmp;
315 if (resScope==
nullptr)
break;
327 bool searchRelated=
false;
328 bool mustBeRelated=
false;
339 if (mn==0 && searchRelated)
347 for (
const auto &tmd_p : *mn)
350 AUTO_TRACE_ADD(
"found candidate member '{}' isTypeDef={}' isRelated={} mustBeRelated={}",
365 if (dist!=-1 && (md==
nullptr || dist<minDist))
411static const char constScope[] = {
'c',
'o',
'n',
's',
't',
':' };
412static const char volatileScope[] = {
'v',
'o',
'l',
'a',
't',
'i',
'l',
'e',
':' };
413static const char virtualScope[] = {
'v',
'i',
'r',
't',
'u',
'a',
'l',
':' };
414static const char operatorScope[] = {
'o',
'p',
'e',
'r',
'a',
't',
'o',
'r',
'?',
'?',
'?' };
420 charMap[
static_cast<int>(
'(')].before=
false;
421 charMap[
static_cast<int>(
'=')].before=
false;
422 charMap[
static_cast<int>(
'&')].before=
false;
423 charMap[
static_cast<int>(
'*')].before=
false;
424 charMap[
static_cast<int>(
'[')].before=
false;
425 charMap[
static_cast<int>(
'|')].before=
false;
426 charMap[
static_cast<int>(
'+')].before=
false;
427 charMap[
static_cast<int>(
';')].before=
false;
428 charMap[
static_cast<int>(
':')].before=
false;
429 charMap[
static_cast<int>(
'/')].before=
false;
431 charMap[
static_cast<int>(
'=')].after=
false;
432 charMap[
static_cast<int>(
' ')].after=
false;
433 charMap[
static_cast<int>(
'[')].after=
false;
434 charMap[
static_cast<int>(
']')].after=
false;
435 charMap[
static_cast<int>(
'\t')].after=
false;
436 charMap[
static_cast<int>(
'\n')].after=
false;
437 charMap[
static_cast<int>(
')')].after=
false;
438 charMap[
static_cast<int>(
',')].after=
false;
439 charMap[
static_cast<int>(
'<')].after=
false;
440 charMap[
static_cast<int>(
'|')].after=
false;
441 charMap[
static_cast<int>(
'+')].after=
false;
442 charMap[
static_cast<int>(
'(')].after=
false;
443 charMap[
static_cast<int>(
'/')].after=
false;
470 if (s.
length()*3>growBufLen)
472 growBufLen = s.
length()*3;
473 growBuf =
static_cast<char *
>(realloc(growBuf,growBufLen+1));
475 if (growBuf==
nullptr)
return s;
477 const char *src=s.
data();
488 while (i<l && isspace(
static_cast<uint8_t
>(src[i])))
495 char nc=i+1<l ? src[i+1] :
' ';
497 auto searchForKeyword = [&](
const char *kw,
size_t &matchLen,
size_t totalLen)
499 if (matchLen<=totalLen && c==kw[matchLen] &&
534 if (c==
'\\' && i+1<l)
558 if (i>0 && !isspace(
static_cast<uint8_t
>(pc)) &&
559 (
isId(pc) || pc==
'*' || pc==
'&' || pc==
'.' || pc==
'>') &&
560 (osp<8 || (osp==8 && pc!=
'-'))
566 if (i+1<l && (nc==
'-' || nc==
'&'))
573 if (i>0 && !isspace(
static_cast<uint8_t
>(pc)) &&
574 ((i+1<l && (
isId(nc) || nc==
'[')) ||
575 (i+2<l && nc==
'$' &&
isId(src[i+2])) ||
576 (i+3<l && nc==
'&' && src[i+2]==
'$' &&
isId(src[i+3]))
586 if (cliSupport && i+1<l && (
isId(nc) || nc==
'-'))
593 if (i+1<l && (
isId(nc) || nc==
'-'))
599 if (i>0 && pc!=
' ' && pc!=
'\t' && pc!=
':' &&
600 pc!=
'*' && pc!=
'&' && pc!=
'(' && pc!=
'/' && pc!=
'[' &&
610 if (i>0 &&
isId(pc) && osp<9)
630 if (i>0 && i+1<l && pc!=
'=' && pc!=
':' && !isspace(
static_cast<uint8_t
>(pc)) &&
661 !(pc==
',' && nc==
'.') &&
662 (osp<8 || (osp>=8 &&
isId(pc) &&
isId(nc)))
670 else if ((pc==
'*' || pc==
'&' || pc==
'.') && nc==
'>')
678 auto correctKeywordAllowedInsideScope = [&](
char cc,
size_t &matchLen,
size_t totalLen) {
679 if (c==cc && matchLen==totalLen)
681 if ((i+2<l && src[i+1] ==
':' && src[i+2] ==
':') ||
682 ((i>matchLen && src[i-matchLen] ==
':' && src[i-matchLen-1] ==
':'))
686 correctKeywordAllowedInsideScope(
't',csp, 5);
687 correctKeywordAllowedInsideScope(
'e',vosp,8);
688 correctKeywordAllowedInsideScope(
'l',vsp, 7);
690 auto correctKeywordNotPartOfScope = [&](
char cc,
size_t &matchLen,
size_t totalLen)
692 if (c==cc && matchLen==totalLen && i+1<l &&
700 correctKeywordNotPartOfScope(
't',csp, 5);
701 correctKeywordNotPartOfScope(
'e',vosp,8);
702 correctKeywordNotPartOfScope(
'l',vsp, 7);
722 if (templateDepth > 0)
724 size_t nextOpenPos = name.
rfind(
'>', pos);
725 size_t nextClosePos = name.
rfind(
'<', pos);
743 size_t lastAnglePos = name.
rfind(
'>', pos);
744 size_t bracePos = name.
rfind(
'(', pos);
754 return bp==
DString::npos || (bp>=8 && name.
mid(bp-8,10)==
"operator()") ? bracePos : bp;
765 return (name==scope ||
766 (scope.
right(nl)==name &&
767 sl>1+nl && scope.
at(sl-nl-1)==
':' && scope.
at(sl-nl-2)==
':'
776 return (name==scope ||
777 (name.
left(sl)==scope &&
778 nl>sl+1 && name.
at(sl)==
':' && name.
at(sl+1)==
':'
786 std::function<
void(
size_t)> replaceFunc)
788 static const reg::Ex marker(R
"(@(\d+))");
792 for ( ; it!=
end ; ++it)
794 const auto &match = *it;
795 size_t newIndex = match.position();
796 size_t matchLen = match.length();
797 ol.
parseText(markerText.substr(index,newIndex-index));
798 unsigned long entryIndex = std::stoul(match[1].str());
799 if (entryIndex<
static_cast<unsigned long>(numMarkers))
801 replaceFunc(entryIndex);
803 index=newIndex+matchLen;
809 std::function<
DString(
size_t)> replaceFunc)
812 static const reg::Ex marker(R
"(@(\d+))");
816 for ( ; it!=
end ; ++it)
818 const auto &match = *it;
819 size_t newIndex = match.position();
820 size_t matchLen = match.length();
821 result += markerText.
substr(index,newIndex-index);
822 unsigned long entryIndex = std::stoul(match[1].str());
823 if (entryIndex<
static_cast<unsigned long>(numMarkers))
825 result+=replaceFunc(entryIndex);
827 index=newIndex+matchLen;
829 if (index<markerText.size())
831 result += markerText.
substr(index);
838 auto replaceFunc = [&list,&ol](
size_t entryIndex)
840 const auto &e = list[entryIndex];
875 paramDocs+=
" \\ilinebr @tparam "+a.name+
" "+a.docs;
877 else if (!a.type.empty())
883 paramDocs+=
" \\ilinebr @tparam "+type+
" "+a.docs;
896 for (
auto it = al.
begin() ; it!=al.
end() ;)
916 result+= type1+type2;
923 if (it!=al.
end()) result+=
", ";
938 if (al.
empty())
return result;
941 for (
const auto &a : al)
943 if (a.defval.empty() || includeDefault)
945 if (!first) result+=
", ";
948 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp)
956 int i =
static_cast<int>(a.type.length())-1;
957 while (i>=0 &&
isId(a.type.at(i))) i--;
960 result+=a.type.
right(a.type.length()-i-1);
971 if (!a.typeConstraint.empty() && lang==SrcLangExt::Java)
974 result+=a.typeConstraint;
995 size_t len = contents.length();
999 char c = contents[src++];
1003 if (src<len && contents[src] ==
'\n')
1008 else if ( c ==
'\0' && src<len-1)
1012 contents[dest++] = c;
1014 contents.resize(dest);
1021 for (
const auto &filterStr : filterList)
1030 filterPattern = filterPattern.
lower();
1031 input = input.
lower();
1040 filterName=
"\""+filterName+
"\"";
1055 if (name.
empty())
return "";
1062 if (isSourceCode && !filterSrcList.empty())
1066 if (!found && filterName.
empty())
1077 if (filterName.
length()>=2 && filterName[0]==
'"' && filterName[
static_cast<int>(filterName.
length())-1]==
'"')
1079 filterName = filterName.
mid(1,filterName.
length()-2);
1088 const char *outputEncoding =
"UTF-8";
1089 if (inputEncoding==
nullptr ||
dstricmp(inputEncoding,outputEncoding)==0)
return true;
1090 size_t inputSize=input.length();
1091 size_t outputSize=inputSize*4;
1094 if (cd==
reinterpret_cast<void *
>(-1))
1099 size_t iLeft=inputSize;
1100 size_t oLeft=outputSize;
1101 const char *inputPtr = input.data();
1102 char *outputPtr = output.
rawData();
1105 outputSize-=
static_cast<int>(oLeft);
1106 output.
resize(outputSize);
1107 output.
at(outputSize)=
'\0';
1123 bool fileOpened=
false;
1124 if (name[0]==
'-' && name[1]==0)
1126 std::string contents;
1128 while (getline(std::cin,line))
1130 contents+=line+
'\n';
1139 err(
"file '{}' not found\n",name);
1152 err(
"cannot open file '{}' for reading\n",name);
1160 for (
const auto &bcd : bcl)
1180 AUTO_TRACE(
"target='{}' str='{}'",target,str);
1181 if (target==str) { target.
clear();
return; }
1188 for (
size_t q=p;q<i;q++)
1190 if (target[q]==
'<') sharpCount++;
1191 else if (target[q]==
'>' && sharpCount>0) sharpCount--;
1193 bool isMatch = (i==0 || !
isId(target.
at(i-1))) &&
1195 !insideTemplate && sharpCount==0;
1198 size_t i1=target.
find(
'*',i+l);
1199 size_t i2=target.
find(
'&',i+l);
1203 target=target.
left(i)+target.
mid(i+l);
1210 target=str+
" "+target.
left(i)+target.
mid(i+l);
1250 size_t i=s.
find(
" class ");
1252 i=s.
find(
" typename ");
1254 i=s.
find(
" union ");
1256 i=s.
find(
" struct ");
1270 if (!templSpec.
empty() && templSpec.
at(0) ==
'<')
1275 if (!resolvedType.
empty())
1277 templSpec = resolvedType;
1289 if (count>10)
return word;
1291 DString symName,result,templSpec,tmpName;
1292 if (tSpec && !tSpec->
empty())
1295 AUTO_TRACE(
"d='{}' fs='{}' word='{}' templSpec='{}'",d?d->
name():
"",fs?fs->
name():
"",word,templSpec);
1313 bool isTemplInst = cd && !templSpec.
empty();
1314 if (!cd && !templSpec.
empty())
1325 cd?cd->
name():
"",mType?mType->
name():
"",ts,resolvedType);
1348 if (cd==d && tSpec) *tSpec=
"";
1352 result = resolvedType+ts;
1360 if (tSpec) *tSpec=
"";
1372 if (!templSpec.
empty())
1374 result=cd->
name()+templSpec;
1424 resolvedType = lang==SrcLangExt::Java ? word :
resolveTypeDef(d,word);
1426 if (resolvedType.
empty())
1432 result = resolvedType;
1467 if (i-pp>=2 && type[i-2]==
':' && type[i-1]==
':')
1469 canType += type.
mid(pp,i-pp-2);
1473 canType += type.
mid(pp,i-pp);
1482 if (ct.
empty() && type.
mid(p,2)==
"::")
1492 if (!templSpec.
empty())
1496 std::string ts = templSpec.
str();
1497 static const reg::Ex re(R
"(\a\w*)");
1504 for (; it!=
end ; ++it)
1506 const auto &match = *it;
1507 size_t ti = match.position();
1508 size_t tl = match.length();
1509 std::string matchStr = match.str();
1510 canType += ts.
substr(tp,ti-tp);
1519 canType += type.
mid(pp);
1530 if ((type==
"const" || type==
"volatile") && !name.
empty())
1535 if (name==
"const" || name==
"volatile")
1537 if (!type.
empty()) type+=
" ";
1555#define MATCH AUTO_TRACE_EXIT("match at line {}",__LINE__);
1556#define NOMATCH AUTO_TRACE_EXIT("no match at line {}",__LINE__);
1563 AUTO_TRACE(
"srcType='{}' dstType='{}'",srcType,dstType);
1564 if (srcType==dstType)
return true;
1567 size_t i1=srcType.
find(
")(");
1569 size_t i2=dstType.
find(
")(");
1570 if (i1!=i2)
return false;
1573 size_t j1=srcType.
find(
"(");
1575 size_t j2=dstType.
find(
"(");
1576 if (j2!=j1)
return false;
1577 if (srcType.
left(j1)!=dstType.
left(j2))
return false;
1586 dstScope,dstFileScope,dstType.
left(j2),dstAl.get(),
1596 AUTO_TRACE(
"src: scope={} type={} name={} canType={}, dst: scope={} type={} name={} canType={}",
1615 srcA.
type+=sSrcName;
1619 else if (sDstName==srcType.
right(sDstName.
length()))
1621 dstA.
type+=sDstName;
1637 dstScope,dstFileScope,dstA.
canType,
1660 ASSERT(srcScope!=
nullptr && dstScope!=
nullptr);
1662 AUTO_TRACE(
"srcScope='{}' dstScope='{}' srcArgs='{}' dstArgs='{}' checkCV={} lang={}",
1665 if (srcAl==
nullptr || dstAl==
nullptr)
1667 bool match = srcAl==dstAl;
1698 if (srcAl->
size() != dstAl->
size())
1732 auto srcIt = srcAl->
begin();
1733 auto dstIt = dstAl->
begin();
1734 for (;srcIt!=srcAl->
end() && dstIt!=dstAl->
end();++srcIt,++dstIt)
1739 dstScope,dstFileScope,dstA,
1758 AUTO_TRACE(
"srcAl='{}',dstAl='{}',forceNameOverwrite={}",
1766 auto srcIt=srcAl.
begin();
1767 auto dstIt=dstAl.
begin();
1768 while (srcIt!=srcAl.
end() && dstIt!=dstAl.
end())
1773 AUTO_TRACE_ADD(
"before merge: src=[type='{}',name='{}',def='{}'] dst=[type='{}',name='{}',def='{}']",
1789 if (srcA.
name==
"const" || srcA.
name==
"volatile")
1794 if (dstA.
name==
"const" || dstA.
name==
"volatile")
1820 if (forceNameOverwrite)
1892 AUTO_TRACE_ADD(
"after merge: src=[type='{}',name='{}',def='{}'] dst=[type='{}',name='{}',def='{}']",
1908 auto isUnconstraintTemplate = [](
const DString &type)
1910 return type==
"typename" || type==
"class" || type.startsWith(
"typename ") || type.startsWith(
"class ");
1912 auto srcIt = srcAl.
begin();
1913 auto dstIt = dstAl.
begin();
1914 while (srcIt!=srcAl.
end() && dstIt!=dstAl.
end())
1918 if ((!isUnconstraintTemplate(srcA.
type) || !isUnconstraintTemplate(dstA.
type)) && srcA.
type!=dstA.
type)
1937 AUTO_TRACE(
"scopeName={},memberName={},forceEmptyScope={}",
1963 result.
found =
true;
1968 result.
found =
true;
1973 result.
found =
true;
1978 result.
found =
true;
1983 result.
found =
true;
2013 if (scopeName.
empty())
return false;
2015 bool explicitGlobalScope=
false;
2016 if (scopeName.
at(0)==
':' && scopeName.
at(1)==
':')
2018 scopeName=scopeName.
mid(2);
2019 explicitGlobalScope=
true;
2021 if (scopeName.
empty())
2026 DString docScopeName=docScope;
2027 int scopeOffset=explicitGlobalScope ? 0 :
static_cast<int>(docScopeName.
length());
2032 if (scopeOffset>0) fullName.
prepend(docScopeName.
left(scopeOffset)+
"::");
2058 size_t o = docScopeName.
rfind(
"::",scopeOffset-1);
2061 }
while (scopeOffset>=0);
2068 if (s.
empty())
return true;
2069 const char *p=s.
data();
2071 while ((c=
static_cast<uint8_t
>(*p++)))
if (!islower(c))
return false;
2081 bool lookForSpecialization,
2086 AUTO_TRACE(
"scope={} name={} inSeeBlock={} lang={} lookForSpecialization={} currentFile={} checkScope={}",
2087 scName,name,inSeeBlock,lang,lookForSpecialization,currentFile ? currentFile->
name() :
"", checkScope);
2101 size_t templStartPos;
2102 if (lang==SrcLangExt::CSharp && (templStartPos=fullName.
find(
'<'))!=
DString::npos)
2104 size_t templEndPos = fullName.
rfind(
'>');
2114 size_t scopePos = fullName.
rfind(
"::",endNamePos);
2115 bool explicitScope = fullName.
startsWith(
"::") &&
2120 bool allowTypeOnly=
false;
2123 *resContext=
nullptr;
2144 if (scName!=fullName &&
getScopeDefs(scName,fullName,cd,cnd,nd,modd))
2167 else if (scName==fullName || (!inSeeBlock && scopePos==
DString::npos))
2186 if (explicitScope) nameStr=nameStr.
mid(2);
2195 size_t templPos = nameStr.
find(
'<');
2196 bool tryUnspecializedVersion =
false;
2199 size_t endTemplPos=nameStr.
rfind(
'>');
2202 if (!lookForSpecialization)
2204 nameStr=nameStr.
left(templPos)+nameStr.
mid(endTemplPos+1);
2208 tryUnspecializedVersion =
true;
2216 nameStr=nameStr.
mid(scopeStr.
length()+2);
2234 size_t np = nameStr.
find(
"::");
2243 *resContext=
nullptr;
2253 *resMember=result.
md;
2254 *resContext=result.
md;
2258 *resContext=
nullptr;
2264 else if (result.
cd) *resContext=result.
cd;
2265 else if (result.
nd) *resContext=result.
nd;
2266 else if (result.
fd) *resContext=result.
fd;
2267 else if (result.
gd) *resContext=result.
gd;
2268 else if (result.
cnd) *resContext=result.
cnd;
2269 else if (result.
modd) *resContext=result.
modd;
2272 *resContext=
nullptr; *resMember=
nullptr;
2311 if (tryUnspecializedVersion)
2313 bool b =
resolveRef(scName,name,inSeeBlock,resContext,resMember,lang,
false,
nullptr,checkScope);
2336 if (!result.
empty())
2343 if (result.
at(0)==
':' && result.
at(1)==
':')
2345 result=result.
mid(2);
2364 for (
const auto &path : stripPaths)
2384 *resContext=
nullptr;
2387 if (lang==SrcLangExt::CSharp)
2392 AUTO_TRACE(
"scName='{}',ref='{}'",scName,lr);
2397 const DirDef *dir =
nullptr;
2403 if (linkRef.
empty())
2415 if (si) resAnchor = si->
label();
2427 resAnchor = si->
label();
2434 resAnchor = si->
label();
2464 else if (lang==SrcLangExt::Java &&
2465 (cd=
getClass(linkRefWithoutTemplates)))
2472 else if ((cd=
getClass(linkRef+
"-p")))
2489 resAnchor=modd->
anchor();
2508 bool res =
resolveRef(scName,lr,
true,resContext,&md,lang);
2509 if (md) resAnchor=md->
anchor();
2535 for (
const auto &s : examplePathList)
2563 std::string substRes;
2565 const char *p = s.
data();
2569 substRes.reserve(s.
length()+1024);
2576 for (
const auto &kw : keywords)
2578 size_t keyLen =
dstrlen(kw.keyword);
2579 if (
dstrncmp(p,kw.keyword,keyLen)==0)
2581 const char *startArg = p+keyLen;
2582 bool expectParam = std::holds_alternative<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
2584 if (expectParam && *startArg==
'(')
2587 const char *endArg =
nullptr;
2588 while ((c=*(startArg+j)) && c!=
')' && c!=
'\n' && c!=0) j++;
2589 if (c==
')') endArg=startArg+j;
2593 auto &&getValue = std::get<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
2594 substRes+=getValue(value).str();
2601 warn(file,line,
"Missing argument for '{}'",kw.keyword);
2605 else if (!expectParam)
2607 auto &&getValue = std::get<KeywordSubstitution::GetValue>(kw.getValueVariant);
2608 substRes+=getValue().str();
2615 warn(file,line,
"Expected arguments for '{}' but none were specified",kw.keyword);
2625 if (c==
'\n') line++;
2650 if (!projectLogo.
empty())
2655 projectLogo = projectLogo.
left(wi);
2659 projectLogo = projectLogo.
left(hi);
2670 if (!projectLogo.
empty())
2672 auto extractDimension = [&projectLogo](
const char *startMarker,
size_t startPos,
size_t endPos) ->
DString
2675 if (result.
length()>=2 && result.
at(0)!=
'"' && result.
at(result.
length()-1)!=
'"')
2677 result=
"\""+result+
"\"";
2683 size_t wi = projectLogo.
find(
" width=");
2684 size_t hi = projectLogo.
find(
" height=");
2689 sizeVal = extractDimension(
" width=", wi+7, hi) +
" "
2690 + extractDimension(
" height=", hi+8, projectLogo.
length());
2694 sizeVal = extractDimension(
" height=", hi+8, wi) +
" "
2695 + extractDimension(
" width=", wi+7, projectLogo.
length());
2700 sizeVal = extractDimension(
" width=", wi+7, projectLogo.
length());
2704 sizeVal = extractDimension(
" height=", hi+8, projectLogo.
length());
2720 if (name.
empty())
return 0;
2723 for (
const auto &s : sl)
2725 const char *ps=s.c_str();
2726 const char *pd=name.
data();
2728 while (*ps!=0 && *pd!=0 && *ps==*pd)
2734 if (*ps==0 && *pd!=0)
2740 if (result<
static_cast<int>(name.
length())-1 && name.
at(result)==
'[') result++;
2750 if (caseSenseNames == CASE_SENSE_NAMES_t::YES)
return true;
2751 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO)
return false;
2757 if (name.
empty())
return name;
2763 const char *p=name.
data();
2768 case '_':
if (allowUnderscore) result+=
'_';
else result+=
"__";
break;
2769 case '-': result+=
'-';
break;
2770 case ':': result+=
"_1";
break;
2771 case '/': result+=
"_2";
break;
2772 case '<': result+=
"_3";
break;
2773 case '>': result+=
"_4";
break;
2774 case '*': result+=
"_5";
break;
2775 case '&': result+=
"_6";
break;
2776 case '|': result+=
"_7";
break;
2777 case '.':
if (allowDots) result+=
'.';
else result+=
"_8";
break;
2778 case '!': result+=
"_9";
break;
2779 case ',': result+=
"_00";
break;
2780 case ' ': result+=
"_01";
break;
2781 case '{': result+=
"_02";
break;
2782 case '}': result+=
"_03";
break;
2783 case '?': result+=
"_04";
break;
2784 case '^': result+=
"_05";
break;
2785 case '%': result+=
"_06";
break;
2786 case '(': result+=
"_07";
break;
2787 case ')': result+=
"_08";
break;
2788 case '+': result+=
"_09";
break;
2789 case '=': result+=
"_0a";
break;
2790 case '$': result+=
"_0b";
break;
2791 case '\\': result+=
"_0c";
break;
2792 case '@': result+=
"_0d";
break;
2793 case ']': result+=
"_0e";
break;
2794 case '[': result+=
"_0f";
break;
2795 case '#': result+=
"_0g";
break;
2796 case '"': result+=
"_0h";
break;
2797 case '~': result+=
"_0i";
break;
2798 case '\'': result+=
"_0j";
break;
2799 case ';': result+=
"_0k";
break;
2800 case '`': result+=
"_0l";
break;
2804 bool doEscape =
true;
2805 if (allowUnicodeNames)
2818 unsigned char id =
static_cast<unsigned char>(c);
2827 else if (caseSenseNames || !isupper(c))
2834 result+=
static_cast<char>(tolower(c));
2844 if (s.
empty())
return s;
2848 const char *p = s.
data();
2858 case '_': result+=c; p++;
break;
2859 case '1': result+=
':'; p++;
break;
2860 case '2': result+=
'/'; p++;
break;
2861 case '3': result+=
'<'; p++;
break;
2862 case '4': result+=
'>'; p++;
break;
2863 case '5': result+=
'*'; p++;
break;
2864 case '6': result+=
'&'; p++;
break;
2865 case '7': result+=
'|'; p++;
break;
2866 case '8': result+=
'.'; p++;
break;
2867 case '9': result+=
'!'; p++;
break;
2871 case '0': result+=
','; p+=2;
break;
2872 case '1': result+=
' '; p+=2;
break;
2873 case '2': result+=
'{'; p+=2;
break;
2874 case '3': result+=
'}'; p+=2;
break;
2875 case '4': result+=
'?'; p+=2;
break;
2876 case '5': result+=
'^'; p+=2;
break;
2877 case '6': result+=
'%'; p+=2;
break;
2878 case '7': result+=
'('; p+=2;
break;
2879 case '8': result+=
')'; p+=2;
break;
2880 case '9': result+=
'+'; p+=2;
break;
2881 case 'a': result+=
'='; p+=2;
break;
2882 case 'b': result+=
'$'; p+=2;
break;
2883 case 'c': result+=
'\\'; p+=2;
break;
2884 case 'd': result+=
'@'; p+=2;
break;
2885 case 'e': result+=
']'; p+=2;
break;
2886 case 'f': result+=
'['; p+=2;
break;
2887 case 'g': result+=
'#'; p+=2;
break;
2888 case 'h': result+=
'"'; p+=2;
break;
2889 case 'i': result+=
'~'; p+=2;
break;
2890 case 'j': result+=
'\''; p+=2;
break;
2891 case 'k': result+=
';'; p+=2;
break;
2892 case 'l': result+=
'`'; p+=2;
break;
2899 if (!caseSenseNames && c>=
'a' && c<=
'z')
2901 result+=
static_cast<char>(toupper(*p));
2932 if (name.
empty())
return name;
2955 size_t resultLen = result.
length();
2964 int l1Dir=0,l2Dir=0;
2965 int createSubdirsLevel =
Config_getInt(CREATE_SUBDIRS_LEVEL);
2966 int createSubdirsBitmaskL2 = (1<<createSubdirsLevel)-1;
2970 l1Dir = md5_sig[14] & 0xf;
2971 l2Dir = md5_sig[15] & createSubdirsBitmaskL2;
2999 DString absIncFileName = incFileName;
3009 else if (searchIncludes)
3012 for (
const auto &incPath : includePath)
3031 return absIncFileName;
3041 int createSubdirsLevelPow2 = 1 <<
Config_getInt(CREATE_SUBDIRS_LEVEL);
3042 for (
int l1=0; l1<16; l1++)
3048 term(
"Failed to create output directory '{}'\n",subdir);
3050 for (
int l2=0; l2<createSubdirsLevelPow2; l2++)
3053 subsubdir.
sprintf(
"d%x/d%02x",l1,l2);
3056 term(
"Failed to create output directory '{}'\n",subsubdir);
3068 int createSubdirsLevelPow2 = 1 <<
Config_getInt(CREATE_SUBDIRS_LEVEL);
3069 for (
int l1=0;l1<16;l1++)
3073 for (
int l2=0; l2 < createSubdirsLevelPow2; l2++)
3076 subsubdir.
sprintf(
"d%x/d%02x",l1,l2);
3095 bool allowEmptyClass)
3103 namespaceName=nd->
name();
3107 p=
static_cast<int>(clName.
length())-2;
3115 namespaceName=nd->
name();
3116 className=clName.
mid(i+2);
3119 p=
static_cast<int>(i)-2;
3124 className=scopeName;
3125 namespaceName.
clear();
3128 if (className.
empty() && !namespaceName.
empty() && !allowEmptyClass)
3131 className=namespaceName;
3132 namespaceName.
clear();
3138 className = className.
left(className.
length()-2);
3164 result=scope.
left(si) + templ + scope.
mid(si);
3179 int l =
static_cast<int>(result.
length());
3182 bool skipBracket=
false;
3189 while (p>=0 && count>=0)
3191 char c=result.
at(p);
3197 if (p>0 && result.
at(p-1)==
':' && (count==0 || skipBracket))
3199 return result.
right(l-p-1);
3210 if (p>0 && result.
at(p-1)==
'>')
3218 bool foundMatch=
false;
3219 while (p>=0 && !foundMatch)
3231 if (round==0) count++;
3238 if (result.
at(p-1) ==
'<')
3245 foundMatch = count==0;
3260 done = count==0 || skipBracket;
3271 if (s.
empty())
return s;
3274 const char *p = s.
data();
3280 if ((c>=
'0' && c<=
'9') || (c>=
'a' && c<=
'z') || (c>=
'A' && c<=
'Z') || c==
'-')
3282 if (first && c>=
'0' && c<=
'9') result+=
'a';
3288 encChar[1]=
hex[
static_cast<unsigned char>(c)>>4];
3289 encChar[2]=
hex[
static_cast<unsigned char>(c)&0xF];
3301 if (s.
empty())
return s;
3304 const char *p = s.
data();
3310 case '<': result+=
"<";
break;
3311 case '>': result+=
">";
break;
3312 case '&':
if (keepEntities)
3318 if (ce==
';' || (!(
isId(ce) || ce==
'#')))
break;
3324 while (p<e) result+=*p++;
3344 case '\'': result+=
"'";
break;
3345 case '"': result+=
""";
break;
3346 case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
3347 case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
3348 case 19:
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
case 26:
3349 case 27:
case 28:
case 29:
case 30:
case 31:
3351 default: result+=c;
break;
3360 if (s.
empty())
return s;
3363 const char *p=s.
data();
3369 case '<': result+=
"<";
break;
3370 case '>': result+=
">";
break;
3371 case '&':
if (keepEntities)
3377 if (ce==
';' || (!(
isId(ce) || ce==
'#')))
break;
3383 while (p<e) result+=*p++;
3395 case '\'': result+=
"'";
break;
3396 case '"': result+=
""";
break;
3399 uint8_t uc =
static_cast<uint8_t
>(c);
3400 if (uc<32 && !isspace(c))
3404 result+=
hex[uc&0xF];
3420 if (s.
empty())
return s;
3423 const char *p=s.
data();
3429 case '"':
if (!singleQuotes) result+=
"\\\"";
else result+=c;
3431 case '\'':
if (singleQuotes) result+=
"\\\'";
else result+=c;
3433 case '\\':
if (*p==
'u' && *(p+1)==
'{') result+=
"\\";
3434 else result+=
"\\\\";
3436 default: result+=c;
break;
3446 ASSERT(context!=
nullptr);
3448 if (ml==
nullptr)
return;
3450 struct MoveMemberInfo
3453 : memberDef(md), memberGroup(mg), sli(rv) {}
3458 std::vector<MoveMemberInfo> movedMembers;
3460 for (
const auto &md : *ml)
3462 if (md->isEnumerate())
3464 for (
const auto &fmd : md->enumFieldList())
3466 int groupId=fmd->getMemberGroupId();
3472 const auto &info = it->second;
3473 auto mg_it = std::find_if(pMemberGroups->begin(),
3474 pMemberGroups->end(),
3475 [&groupId](
const auto &g)
3476 { return g->groupId()==groupId; }
3479 if (mg_it==pMemberGroups->end())
3481 auto mg = std::make_unique<MemberGroup>(
3490 pMemberGroups->push_back(std::move(mg));
3494 mg_ptr = (*mg_it).get();
3506 int groupId=md->getMemberGroupId();
3512 const auto &info = it->second;
3513 auto mg_it = std::find_if(pMemberGroups->begin(),
3514 pMemberGroups->end(),
3515 [&groupId](
const auto &g)
3516 { return g->groupId()==groupId; }
3519 if (mg_it==pMemberGroups->end())
3521 auto mg = std::make_unique<MemberGroup>(
3530 pMemberGroups->push_back(std::move(mg));
3534 mg_ptr = (*mg_it).get();
3536 movedMembers.emplace_back(md,mg_ptr,info->m_sli);
3542 for (
const auto &mmi : movedMembers)
3544 ml->
remove(mmi.memberDef);
3545 mmi.memberGroup->insertMember(mmi.memberDef->resolveAlias());
3546 mmi.memberGroup->setRefItems(mmi.sli);
3562 AUTO_TRACE(
"type='{}' pos={} name='{}' lang={}",type,pos,name,lang);
3563 static const reg::Ex re_norm(R
"(\a[\w:]*)");
3564 static const reg::Ex re_fortran(R
"(\a[\w:()=]*)");
3574 size_t typeLen=type.
length();
3577 if (lang == SrcLangExt::Fortran)
3589 std::string s = type.
str();
3595 const auto &match = *it;
3596 size_t i = match.position();
3597 size_t l = match.length();
3602 while (ts<typeLen && type[
static_cast<uint32_t
>(ts)]==
' ') { ts++; tl++; }
3603 if (ts<typeLen && type[
static_cast<uint32_t
>(ts)]==
'<')
3608 while (te<typeLen && brCount!=0)
3610 if (type[
static_cast<uint32_t
>(te)]==
'<')
3612 if (te<typeLen-1 && type[
static_cast<uint32_t
>(te)+1]==
'<') te++;
else brCount++;
3614 if (type[
static_cast<uint32_t
>(te)]==
'>')
3616 if (te<typeLen-1 && type[
static_cast<uint32_t
>(te)+1]==
'>') te++;
else brCount--;
3626 pos=
static_cast<int>(i+l+tl);
3630 pos=
static_cast<int>(i+l);
3635 return static_cast<int>(i);
3638 pos =
static_cast<int>(typeLen);
3651 size_t p=name.
find(
'<');
3656 std::string s = name.
mid(p).
str();
3657 static const reg::Ex re(R
"([\a:][\w:]*)");
3662 for (; it!=
end ; ++it)
3664 const auto &match = *it;
3665 size_t i = match.position();
3666 size_t l = match.length();
3667 result += s.
substr(pi,i-pi);
3670 for (
const Argument &formArg : formalArgs)
3672 if (formArg.name == n)
3710 if (formalArgs.
empty())
return nm;
3713 static const reg::Ex re(R
"(\a\w*)");
3714 std::string name = nm.str();
3719 for (; it!=
end ; ++it)
3721 const auto &match = *it;
3722 size_t i = match.position();
3723 size_t l = match.length();
3724 if (i>p) result += name.
substr(p,i-p);
3729 actIt = actualArgs->
begin();
3736 for (
auto formIt = formalArgs.
begin();
3737 formIt!=formalArgs.
end() && !found;
3743 if (actualArgs && actIt!=actualArgs->
end())
3750 formArg.
type =
"class";
3755 formArg.
type =
"typename";
3759 formArg.
name +=
"...";
3764 formArg.
name +=
"...";
3771 if (formArg.
name==n && actualArgs && actIt!=actualArgs->
end() && !actArg.
type.
empty())
3778 ii = subst.find(
'<');
3787 bool beforeNonWord = ii==0 || !
isId(subst.at(ii-1));
3788 bool afterNonWord = subst.length()==ii+nameArg.length() || !
isId(subst.at(ii+nameArg.length()));
3789 if (beforeNonWord && afterNonWord)
3793 pp=ii+nameArg.length();
3798 AUTO_TRACE_ADD(
"result={} n={} type={} hasRecursion={}",result,n,actArg.
type,hasRecursion(result,n,actArg.
type));
3799 if (!hasRecursion(result,n,actArg.
type))
3811 result += actArg.
type;
3817 result += actArg.
type+
" "+actArg.
name;
3822 else if (formArg.
name==n &&
3823 (actualArgs==
nullptr || actIt==actualArgs->
end()) &&
3832 else if (formArg.
name==n &&
3833 (actualArgs==
nullptr || actIt==actualArgs->
end()) &&
3841 if (actualArgs && actIt!=actualArgs->
end())
3870 bool allowArtificial)
3873 size_t i=fullName.
find(
'<');
3877 size_t l=fullName.
length();
3884 while (e<l && count>0)
3886 char c=fullName.
at(e++);
3889 case '(': round++;
break;
3890 case ')':
if (round>0) round--;
break;
3891 case '<':
if (round==0) count++;
break;
3892 case '>':
if (round==0) count--;
break;
3897 size_t si = fullName.
find(
"::",e);
3902 result+=fullName.
mid(p,i-p);
3905 if (cd!=
nullptr && (allowArtificial || !cd->
isArtificial()))
3907 result+=fullName.
mid(i,e-i);
3910 else if (pLastScopeStripped)
3913 *pLastScopeStripped=fullName.
mid(i,e-i);
3916 i=fullName.
find(
'<',p);
3918 result+=fullName.
right(l-p);
3935 AUTO_TRACE(
"leftScope='{}' rightScope='{}'",leftScope,rightScope);
3943 size_t i=0,p=leftScope.
length();
3952 result = leftScope.
left(i+2)+rightScope;
3965 if (!result.
empty() && !rightScope.
empty()) result+=
"::";
3980 int sl=
static_cast<int>(s.
length());
3984 if (sp>=sl)
return -1;
4008 while (sp<sl && !done)
4014 case '<': count++;
break;
4015 case '>': count--;
if (count==0) done=
true;
break;
4048 bool newPage =
true;
4053 warn(fileName,startLine,
"multiple use of page label '{}' with different titles, (other occurrence: {}, line: {})",
4137 else if (si->
lineNr() != -1)
4139 warn(orgFile,line,
"multiple use of section label '{}', (first occurrence: {}, line {})",pd->
name(),si->
fileName(),si->
lineNr());
4143 warn(orgFile,line,
"multiple use of section label '{}', (first occurrence: {})",pd->
name(),si->
fileName());
4168 if (!key.
empty() && key[0]!=
'@')
4173 item->setScope(scope);
4174 item->setName(name);
4175 item->setTitle(title);
4176 item->setArgs(args);
4177 item->setGroup(key);
4225 if (!first) { ol.
writeString(
" | "); }
else first=
false;
4237 if (!first) { ol.
writeString(
" | "); }
else first=
false;
4262 if (fName.
empty())
return;
4263 size_t i_fs = fName.
rfind(
'/');
4264 size_t i_bs = fName.
rfind(
'\\');
4267 size_t i = fName.
find(
'.',p);
4294 result=result.
mid(i+1);
4298 result=result.
mid(i+1);
4314 static reg::Ex re(R
"(\s*(<\a+>)\s*)");
4315 std::string s = sentence.str();
4321 for ( ; it!=
end ; ++it)
4323 const auto match = *it;
4324 std::string part = match[1].str();
4327 size_t i = match.position();
4328 size_t l = match.length();
4329 result+=s.substr(p,i-p);
4330 result+=match.str();
4336 size_t i = match[1].position();
4337 size_t l = match[1].length();
4338 result+=s.substr(p,i-p);
4342 result+=s.substr(p);
4358 const char *p = s.
data();
4361 int i=0,li=-1,l=
static_cast<int>(s.
length());
4365 if (c==
' ' || c==
'\t' || c==
'\r') { i++; p++; }
4366 else if (c==
'\\' &&
literal_at(p,
"\\ilinebr")) { i+=8; li=i; p+=8; }
4367 else if (c==
'\n') { i++; li=i; docLine++; p++; }
4377 if (c==
' ' || c==
'\t' || c==
'\r') { b--; p--; }
4378 else if (c==
'r' && b>=7 &&
literal_at(p-7,
"\\ilinebr")) { bi=b-7; b-=8; p-=8; }
4379 else if (c==
'>' && b>=11 &&
literal_at(p-11,
"\\ilinebr<br>")) { bi=b-11; b-=12; p-=12; }
4380 else if (c==
'\n') { bi=b; b--; p--; }
4385 if (li==-1 && bi==-1)
return s;
4392 return s.
mid(li,bi-li);
4410 {
"idl",
"c", SrcLangExt::IDL,
".idl" },
4411 {
"java",
"c", SrcLangExt::Java,
".java"},
4412 {
"javascript",
"c", SrcLangExt::JS,
".js" },
4413 {
"csharp",
"c", SrcLangExt::CSharp,
".cs" },
4414 {
"d",
"c", SrcLangExt::D,
".d" },
4415 {
"php",
"c", SrcLangExt::PHP,
".php" },
4416 {
"objective-c",
"c", SrcLangExt::ObjC,
".m" },
4417 {
"c",
"c", SrcLangExt::Cpp,
".c" },
4418 {
"c++",
"c", SrcLangExt::Cpp,
".cpp" },
4419 {
"slice",
"c", SrcLangExt::Slice,
".ice" },
4420 {
"python",
"python", SrcLangExt::Python,
".py" },
4421 {
"fortran",
"fortran", SrcLangExt::Fortran,
".f" },
4422 {
"fortranfree",
"fortranfree", SrcLangExt::Fortran,
".f90" },
4423 {
"fortranfixed",
"fortranfixed", SrcLangExt::Fortran,
".f" },
4424 {
"vhdl",
"vhdl", SrcLangExt::VHDL,
".vhdl"},
4425 {
"xml",
"xml", SrcLangExt::XML,
".xml" },
4426 {
"sql",
"sql", SrcLangExt::SQL,
".sql" },
4427 {
"md",
"md", SrcLangExt::Markdown,
".md" },
4428 {
"lex",
"lex", SrcLangExt::Lex,
".l" },
4435 [&langName](
const auto &info) { return info.langName==langName; });
4441 if (extName.
empty())
return false;
4442 if (extName.
at(0)!=
'.') extName.
prepend(
".");
4452 err(
"Failed to assign extension {} to parser {} for language {}\n",
4453 extName.
data(),it1->parserName,language);
4541 if (extName.
empty()) extName=
".no_extension";
4542 if (extName.
at(0)!=
'.') extName.
prepend(
".");
4558 if (lang == SrcLangExt::Unknown)
4562 if (langName.
at(0)==
'.') langName = langName.
mid(1);
4564 [&langName](
const auto &info) { return info.langName==langName; });
4567 lang = it->parserId;
4568 fileName = it->defExt;
4572 return SrcLangExt::Cpp;
4580 if (fn.
empty())
return "";
4590 if (scope==
nullptr ||
4610 if (qualifierIndex!=-1)
4612 explicitScopePart = name.
left(qualifierIndex);
4614 name = name.
mid(qualifierIndex+2);
4618 int minDistance = 10000;
4627 if (distance!=-1 && distance<minDistance)
4629 minDistance = distance;
4643 if (bestMatch && bestMatch->
isTypedef())
4651 if (startPos>=len)
return len;
4652 uint8_t c =
static_cast<uint8_t
>(utf8Str[startPos]);
4657 int (*matcher)(int) =
nullptr;
4658 c =
static_cast<uint8_t
>(utf8Str[startPos+bytes]);
4662 c =
static_cast<uint8_t
>(utf8Str[startPos+bytes]);
4666 matcher = std::isxdigit;
4670 matcher = std::isdigit;
4673 else if (std::isalnum(c))
4676 matcher = std::isalnum;
4680 while ((c =
static_cast<uint8_t
>(utf8Str[startPos+bytes]))!=0 && matcher(c))
4690 return startPos+bytes;
4696 if (doc.
empty())
return "";
4707 .setAutolinkSupport(
false))
4709 auto astImpl =
dynamic_cast<const DocNodeAST*
>(ast.get());
4713 std::visit(visitor,astImpl->root);
4718 int l=
static_cast<int>(result.
length());
4722 if (charCnt>=80)
break;
4729 if (result.
at(i)==
',' ||
4730 result.
at(i)==
'.' ||
4731 result.
at(i)==
'!' ||
4732 result.
at(i)==
'?' ||
4740 if ( i < l) result=result.
left(i)+
"...";
4741 return result.
data();
4760 auto astImpl =
dynamic_cast<const DocNodeAST*
>(ast.get());
4768 std::visit(visitor,astImpl->root);
4785 if (al.
empty())
return;
4802 .setIndexWords(
true));
4812#ifdef TRACINGSUPPORT
4813 void *backtraceFrames[128];
4814 int frameCount = backtrace(backtraceFrames, 128);
4815 const size_t cmdLen = 40960;
4816 static char cmd[cmdLen];
4818 p += snprintf(p,cmdLen,
"/usr/bin/atos -p %d ", (
int)getpid());
4819 for (
int x = 0; x < frameCount; x++)
4821 p += snprintf(p,cmdLen,
"%p ", backtraceFrames[x]);
4823 fprintf(stderr,
"========== STACKTRACE START ==============\n");
4827 while (
size_t len = fread(resBuf, 1,
sizeof(resBuf), fp))
4829 fwrite(resBuf, 1, len, stderr);
4833 fprintf(stderr,
"============ STACKTRACE END ==============\n");
4841 if (inputEncoding.
empty() || outputEncoding.
empty())
return;
4842 if (
dstricmp(inputEncoding,outputEncoding)==0)
return;
4844 if (cd==
reinterpret_cast<void *
>(-1))
4846 term(
"unsupported character conversion: '{}'->'{}': {}\n"
4847 "Check the INPUT_ENCODING setting in the config file!\n",
4848 inputEncoding,outputEncoding,strerror(errno));
4850 size_t iLeft = contents.size();
4851 const char *srcPtr = contents.data();
4852 size_t tmpBufSize = contents.size()*4+1;
4853 size_t oLeft = tmpBufSize;
4855 tmpBuf.resize(tmpBufSize);
4856 char *dstPtr = tmpBuf.data();
4860 newSize = tmpBufSize-oLeft;
4861 tmpBuf.resize(newSize);
4862 std::swap(contents,tmpBuf);
4867 term(
"{}: failed to translate characters from {} to {}: check INPUT_ENCODING\n",
4868 fileName,inputEncoding,outputEncoding);
4878 if (!fi.
exists())
return false;
4880 if (filterName.
empty() || !filter)
4885 err(
"could not open file {}\n",fileName);
4889 auto fileSize = fi.
size();
4890 contents.resize(fileSize);
4891 f.read(contents.data(),fileSize);
4894 err(
"problems while reading file {}\n",fileName);
4900 DString cmd=filterName+
" \""+fileName+
"\"";
4905 err(
"could not execute filter {}\n",filterName);
4908 const int bufSize=4096;
4911 while ((numRead=
static_cast<int>(fread(buf,1,bufSize,f)))>0)
4914 contents.append(buf,numRead);
4921 if (contents.size()>=2 &&
4922 static_cast<uint8_t
>(contents[0])==0xFF &&
4923 static_cast<uint8_t
>(contents[1])==0xFE
4928 else if (contents.size()>=2 &&
4929 static_cast<uint8_t
>(contents[0])==0xFE &&
4930 static_cast<uint8_t
>(contents[1])==0xFF
4935 else if (contents.size()>=3 &&
4936 static_cast<uint8_t
>(contents[0])==0xEF &&
4937 static_cast<uint8_t
>(contents[1])==0xBB &&
4938 static_cast<uint8_t
>(contents[2])==0xBF
4941 contents.erase(0,3);
4957 std::string t = title.
str();
4958 static const reg::Ex re(R
"(%[a-z_A-Z]+)");
4962 for (; it!=
end ; ++it)
4964 const auto &match = *it;
4965 size_t i = match.position();
4966 size_t l = match.length();
4967 if (i>p) tf+=t.substr(p,i-p);
4968 tf+=match.str().substr(1);
4977template<
class PatternList,
class PatternElem,
typename PatternGet = DString(*)(const PatternElem &)>
4979 const PatternList &patList,
4986 if (!patList.empty())
4992 for (
const auto &li : patList)
4994 std::string pattern = getter(li).str();
4995 if (!pattern.empty())
4997 size_t i=pattern.find(
'=');
4998 if (i!=std::string::npos) pattern=pattern.substr(0,i);
5000 if (!caseSenseNames)
5002 pattern =
DString(pattern).lower().str();
5003 fn =
DString(fn).lower().str();
5004 fp =
DString(fp).lower().str();
5005 afp =
DString(afp).lower().str();
5031 auto getter = [](std::string s) ->
DString {
return s; };
5052 if (extLinksInWindow)
5053 return "target=\"_blank\" ";
5055 return "target=\"_parent\" ";
5064 const DString &targetFileName,
5072 if (!targetFileName.
empty())
5077 if (!anchor.
empty() && isLocalFile)
5088 if (!anchor.
empty())
5105 result = it->second;
5106 size_t l = result.
length();
5107 if (!relPath.
empty() && l>0 && result.
at(0)==
'.')
5112 if (l>0 && result.
at(l-1)!=
'/') result+=
'/';
5113 if (!href) result.
append(
"\" ");
5132 std::string s=str.
str();
5133 static const reg::Ex re(R
"(##[0-9A-Fa-f][0-9A-Fa-f])");
5139 size_t sl=s.length();
5141 for (; it!=
end ; ++it)
5143 const auto &match = *it;
5144 size_t i = match.position();
5145 size_t l = match.length();
5146 if (i>p) result+=s.substr(p,i-p);
5147 std::string lumStr = match.str().substr(2);
5148#define HEXTONUM(x) (((x)>='0' && (x)<='9') ? ((x)-'0') : \
5149 ((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \
5150 ((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0)
5152 double r = 0,g = 0,b = 0;
5155 pow(level/255.0,gamma/100.0),&r,&g,&b);
5156 int red =
static_cast<int>(r*255.0);
5157 int green =
static_cast<int>(g*255.0);
5158 int blue =
static_cast<int>(b*255.0);
5161 colStr[1]=
hex[red>>4];
5162 colStr[2]=
hex[red&0xf];
5163 colStr[3]=
hex[green>>4];
5164 colStr[4]=
hex[green&0xf];
5165 colStr[5]=
hex[blue>>4];
5166 colStr[6]=
hex[blue&0xf];
5172 if (p<sl) result+=s.substr(p);
5183 err(
"could not copy file {} to {}\n",src,dest);
5197 size_t m1 = text.
find(marker);
5205 found = (p<=m1 && m1<i);
5214 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp || lang==SrcLangExt::VHDL || lang==SrcLangExt::Python)
5218 else if (lang==SrcLangExt::PHP && !classScope)
5231 static const std::unordered_set<std::string> schemes = {
5232 "http",
"https",
"ftp",
"ftps",
"sftp",
"file",
"news",
"irc",
"ircs"
5235 size_t colonPos = loc_url.
find(
':');
5259 return (prot!=Protection::Private && prot!=Protection::Package) ||
5260 (prot==Protection::Private && extractPrivate) ||
5261 (prot==Protection::Package && extractPackage);
5268 if (s.
empty())
return s;
5272 const char *p=s.
data();
5275 int minIndent=1000000;
5276 bool searchIndent=
true;
5278 bool skipFirst = skipFirstLine;
5281 if (c==
'\t') { indent+=tabSize - (indent%tabSize); }
5282 else if (c==
'\n') { indent=0; searchIndent=
true; skipFirst=
false; }
5283 else if (c==
' ') { indent++; }
5284 else if (searchIndent && !skipFirst)
5287 if (indent<minIndent) minIndent=indent;
5292 if (minIndent==0)
return substitute(s,
"@ilinebr",
"\\ilinebr");
5298 skipFirst=skipFirstLine;
5307 else if (indent<minIndent && !skipFirst)
5311 int newIndent = indent+tabSize-(indent%tabSize);
5325 else if (c==
'\\' &&
literal_at(p,
"ilinebr "))
5328 result <<
"\\ilinebr ";
5331 for (
int j=0;j<minIndent;j++)
if (*(p+j)==
' ') skipAmount++;
5332 if (skipAmount==minIndent)
5339 result <<
"\\ilinebr";
5350 return result.
str();
5358 if (indentationLevel <= 0 || doc.
empty())
return;
5363 const char *src = doc.
data();
5365 bool insideIndent = !skipFirstLine;
5367 if (!skipFirstLine) cnt = indentationLevel;
5375 insideIndent =
true;
5376 cnt = indentationLevel;
5387 insideIndent =
false;
5397 insideIndent =
false;
5402 doc.
resize(
static_cast<uint32_t
>(dst-doc.
data()));
5411 return ( ((allExternals && fd->
isLinkable()) ||
5429uint32_t getUtf8Code(
const DString& s,
int idx )
5431 const int length = s.
length();
5432 if (idx >= length) {
return 0; }
5433 const uint32_t c0 = (uint8_t)s.
at(idx);
5434 if ( c0 < 0xC2 || c0 >= 0xF8 )
5438 if (idx+1 >= length) {
return 0; }
5439 const uint32_t c1 = ((uint8_t)s.
at(idx+1)) & 0x3f;
5442 return ((c0 & 0x1f) << 6) | c1;
5444 if (idx+2 >= length) {
return 0; }
5445 const uint32_t c2 = ((uint8_t)s.
at(idx+2)) & 0x3f;
5448 return ((c0 & 0x0f) << 12) | (c1 << 6) | c2;
5450 if (idx+3 >= length) {
return 0; }
5452 const uint32_t c3 = ((uint8_t)s.
at(idx+3)) & 0x3f;
5453 return ((c0 & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3;
5465uint32_t getUtf8CodeToLower(
const DString& s,
int idx )
5467 const uint32_t v = getUtf8Code( s, idx );
5468 return v < 0x7f ? tolower( v ) : v;
5480uint32_t getUtf8CodeToUpper(
const DString& s,
int idx )
5482 const uint32_t v = getUtf8Code( s, idx );
5483 return v < 0x7f ? toupper( v ) : v;
5497 std::string s = docs.
str();
5498 static const reg::Ex re(R
"(\[([ inout,]+)\])");
5503 const auto &match = *it;
5504 size_t p = match.position();
5505 size_t l = match.length();
5509 std::string dir = match[1].str();
5511 dir.erase(std::remove_if(dir.begin(),dir.end(),
5512 [](
const char c) { return c==
' ' || c==
','; }
5514 unsigned char ioMask=0;
5515 size_t inIndex = dir.find(
"in");
5516 if ( inIndex!=std::string::npos) { dir.erase( inIndex,2); ioMask|=(1<<0); }
5517 size_t outIndex = dir.find(
"out");
5518 if (outIndex!=std::string::npos) { dir.erase(outIndex,3); ioMask|=(1<<1); }
5519 if (dir.empty() && ioMask!=0)
5522 if (ioMask==((1<<0)|(1<<1)))
return "[in,out]";
5523 else if (ioMask==(1<<0))
return "[in]";
5524 else if (ioMask==(1<<1))
return "[out]";
5538 if (a.hasDocumentation(
true))
5540 DString docsWithoutDir = a.docs;
5547 paramDocs+=
" \\ilinebr @param"+direction+
" "+name+
" "+docsWithoutDir;
5580 *outListType1=inListType;
5583 if (inProt==Protection::Public)
5590 else if (inProt==Protection::Protected)
5598 *outListType2=inListType.
toPublic();
5601 else if (inProt==Protection::Private)
5611 *outListType1=inListType.
toPublic();
5633 size_t i= imgExt.
find(
':');
5639 assert(!f.is_open());
5640 bool fileOpened=
false;
5641 bool writeToStdout=outFile==
"-";
5644 f.basic_ios<char>::rdbuf(std::cout.rdbuf());
5659 fileOpened = f.is_open();
5666 static const std::unordered_set<std::string> fortran_C_keywords = {
5667 "character",
"call",
"close",
"common",
"continue",
5668 "case",
"contains",
"cycle",
"class",
"codimension",
5669 "concurrent",
"contiguous",
"critical"
5672 if (*contents !=
'c' && *contents !=
'C')
return false;
5674 const char *c = contents;
5676 while (*c && *c !=
' ') {keyword += *c; c++;}
5677 keyword = keyword.
lower();
5679 return (fortran_C_keywords.find(keyword.
str()) != fortran_C_keywords.end());
5687 bool skipLine=
false;
5693 size_t sizCont = contents.
length();
5694 for (
size_t i=0;i<sizCont;i++)
5698 switch(contents.
at(i))
5705 column += tabSize-1;
5722 if (column==1)
return true;
5723 if (skipLine)
break;
5726 if (column!=6) skipLine=
true;
5729 if (skipLine)
break;
5730 if (column>=7)
return true;
5752 if (s.
empty())
return s;
5755 auto skipBlock = [&markerInfo](
const char *p,
const SelectionBlock &blk)
5762 size_t len = markerInfo.
endLen;
5763 bool negate = *(p+markerInfo.
endLen)==
'!';
5765 size_t blkNameLen =
dstrlen(blk.name);
5766 if (
dstrncmp(p+len,blk.name,blkNameLen)==0 &&
5770 return p+len+blkNameLen+markerInfo.
closeLen;
5787 const char *p = s.
data();
5797 bool negate = *(p+len)==
'!';
5799 for (
const auto &blk : blockList)
5801 size_t blkNameLen =
dstrlen(blk.name);
5802 if (
dstrncmp(p+len,blk.name,blkNameLen)==0 &&
5805 bool blockEnabled = blk.enabled!=negate;
5807 p+=len+blkNameLen+markerInfo.
closeLen;
5826 size_t len = markerInfo.
endLen;
5827 bool negate = *(p+len)==
'!';
5829 for (
const auto &blk : blockList)
5831 size_t blkNameLen =
dstrlen(blk.name);
5832 if (
dstrncmp(p+len,blk.name,blkNameLen)==0 &&
5836 p+=len+blkNameLen+markerInfo.
closeLen;
5865 if (s.
empty())
return;
5867 const char *p = s.
data();
5876 bool negate = *(p+len)==
'!';
5882 if (markerInfo.
closeLen==0 && *p==
'\n')
5884 warn(fileName,-1,
"Remaining begin replacement with marker '{}'",marker);
5890 warn(fileName,-1,
"Remaining begin replacement with marker '{}'",marker);
5899 size_t len = markerInfo.
endLen;
5900 bool negate = *(p+len)==
'!';
5906 if (markerInfo.
closeLen==0 && *p==
'\n')
5908 warn(fileName,-1,
"Remaining end replacement with marker '{}'",marker);
5914 warn(fileName,-1,
"Remaining end replacement with marker '{}'",marker);
5931 size_t size = s.
length();
5934 const char *data = s.
data();
5937 constexpr auto doxy_nbsp =
"&_doxy_nbsp;";
5938 const int maxIndent=1000000;
5939 int minIndent=maxIndent;
5948 int stop = tabSize - (col%tabSize);
5951 while (stop--) result+=
' ';
5955 if (data[i] ==
'\\')
5961 else if (i+5<size &&
literal_at(data+i,
"iskip"))
5966 else if (i+8<size &&
literal_at(data+i,
"endiskip"))
5998 for (
int j=0;j<bytes-1 && c;j++)
6010 if (!skip && col<minIndent) minIndent=col;
6014 if (minIndent!=maxIndent) refIndent=minIndent;
else refIndent=0;
6029 int l =
static_cast<int>(name.
length());
6030 int lastSepPos = -1;
6031 const char *p = name.
data();
6040 if (sharpCount==0 && p[i+1]==
':' && p[i+2]==
':')
6054 if (ts==-1) ts=0;
else p+=++ts;
6055 for (i=ts;i<l-1;i++)
6058 if (c==
':' && *p==
':') lastSepPos=i;
6093 case '\t': col+=tabSize - (col%tabSize);
6102 for (
int i=0;i<numBytes-1 && (c=*s++);i++) {}
6103 if (c==0)
return col;
6130 size_t idx = result.
find(
'-');
6131 result = result.
left(idx)+templArgs;
6139 size_t i = text.
find(
'"');
6167 file.write( content.
data(), content.
length() );
6172 err(
"Could not open file {} for writing\n",fileName);
This class represents an function or template argument list.
RefQualifierType refQualifier() const
bool pureSpecifier() const
bool hasParameters() const
DString trailingReturnType() const
typename Vec::const_iterator const_iterator
bool constSpecifier() const
bool hasDocumentation(bool allowEmptyNames=false) const
bool hasTemplateDocumentation() const
bool volatileSpecifier() const
A abstract class representing of a compound symbol.
virtual const ArgumentList & templateArguments() const =0
Returns the template arguments of this class.
virtual bool isTemplate() const =0
Returns true if this class is a template.
virtual const BaseClassList & baseClasses() const =0
Returns the list of base classes from which this class directly inherits.
virtual DString qualifiedNameWithTemplateParameters(const ArgumentLists *actualParams=nullptr, uint32_t *actualParamIndex=nullptr) const =0
virtual FileDef * getFileDef() const =0
Returns the namespace this compound is in, or 0 if it has a global scope.
virtual bool isUsedOnly() const =0
static void hsl2rgb(double h, double s, double l, double *pRed, double *pGreen, double *pBlue)
virtual const FileDef * getFileDef() const =0
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
DString & setNum(short n)
void resize(size_t newlen)
size_t rfind(char c, size_t pos=npos) const
DString mid(size_t index, size_t len=npos) const
DString simplifyWhiteSpace() const
return a copy of this string with leading and trailing whitespace removed and multiple whitespace cha...
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
DString substr(size_t pos=0, size_t count=npos) const
Returns a substring of length count starting at pos.
char * rawData()
Returns a writable pointer to the data.
std::string_view view() const
static constexpr size_t npos
value used to indicate 'not found' or 'to the end of the string', matching std::string::npos
char & at(size_t i)
Returns a reference to the character at index i.
DString right(size_t len) const
DString & prepend(const char *s)
int contains(char c, bool cs=true) const
size_t find(char c, size_t pos=0) const
DString & sprintf(const char *format,...)
void reserve(size_t size)
Reserve space for size bytes without changing the string contents.
DString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
DString left(size_t len) const
const std::string & str() const
bool stripPrefix(const DString &prefix)
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
bool startsWith(const char *s) const
bool endsWith(const char *s) const
size_t length() const
Returns the length of the string, not counting the 0-terminator.
static void print(DebugMask mask, int prio, fmt::format_string< Args... > fmt, Args &&... args)
The common base class of all entity definitions found in the sources.
virtual SrcLangExt getLanguage() const =0
Returns the programming language this definition was written in.
virtual int docLine() const =0
virtual bool isLinkable() const =0
virtual DefType definitionType() const =0
virtual const DString & name() const =0
virtual bool isLinkableInProject() const =0
virtual DString displayName(bool includeScope=true) const =0
virtual DString qualifiedName() const =0
virtual DString anchor() const =0
virtual DString getReference() const =0
virtual const GroupList & partOfGroups() const =0
virtual bool isArtificial() const =0
virtual Definition * getOuterScope() const =0
virtual DString docFile() const =0
virtual int getStartBodyLine() const =0
virtual bool isReference() const =0
virtual const Definition * findInnerCompound(const DString &name) const =0
virtual DString getOutputFileBase() const =0
virtual void setBodySegment(int defLine, int bls, int ble)=0
virtual void setReference(const DString &r)=0
virtual void setDocumentation(const DString &d, const DString &docFile, int docLine, bool stripWhiteSpace=true)=0
virtual void setLanguage(SrcLangExt lang)=0
virtual void setRefItems(const RefItemVector &sli)=0
A model of a directory symbol.
Class representing a directory in the file system.
bool mkdir(const std::string &path, bool acceptsAbsPath=true) const
bool remove(const std::string &path, bool acceptsAbsPath=true) const
bool empty(const std::string &subdir) const
bool rmdir(const std::string &path, bool acceptsAbsPath=true) const
bool rename(const std::string &orgName, const std::string &newName, bool acceptsAbsPath=true) const
Class representing the abstract syntax tree of a documentation block.
static NamespaceLinkedMap * namespaceLinkedMap
static ConceptLinkedMap * conceptLinkedMap
static std::unique_ptr< PageDef > mainPage
static FileNameLinkedMap * inputNameLinkedMap
static ParserManager * parserManager
static InputFileEncodingList inputFileEncodingList
static MemberNameLinkedMap * functionNameLinkedMap
static PageLinkedMap * exampleLinkedMap
static NamespaceDefMutable * globalScope
static MemberGroupInfoMap memberGroupInfoMap
static StringMap tagDestinationMap
static PageLinkedMap * pageLinkedMap
static DString htmlFileExtension
static DirLinkedMap * dirLinkedMap
static MemberNameLinkedMap * memberNameLinkedMap
static SymbolMap< Definition > * symbolMap
static FileNameLinkedMap * exampleNameLinkedMap
static GroupLinkedMap * groupLinkedMap
A model of a file symbol.
virtual ModuleDef * getModuleDef() const =0
virtual bool generateSourceFile() const =0
virtual DString absFilePath() const =0
virtual bool isDocumentationFile() const =0
Minimal replacement for QFileInfo.
FileInfo(const std::string &name)
std::string extension(bool complete) const
std::string fileName() const
std::string dirPath(bool absPath=true) const
std::string filePath() const
std::string absFilePath() const
FileDef * findFileDef(const DString &n, bool &ambig) const
Returns the file definition in fnMap that matches the file name n.
A model of a group of symbols.
virtual void addPage(PageDef *def)=0
Generator for HTML code fragments.
Concrete visitor implementation for HTML output.
const char * writeHtmlEntity(T &result, const char *s, HtmlEntityMapperFunc &&mapper, const char *fallback)
const char * xml(SymType symb) const
Access routine to the XML code of the HTML entity.
static HtmlEntityMapper & instance()
Returns the one and only instance of the HTML entity mapper.
DString convertCharEntitiesToUTF8(const DString &s) const
T * add(const char *k, Args &&... args)
const T * find(const std::string &key) const
A model of a class/file/namespace member symbol.
virtual DString argsString() const =0
virtual bool isRelated() const =0
virtual const ClassDef * getClassDef() const =0
virtual bool hasReferencesRelation() const =0
virtual GroupDef * getGroupDef()=0
virtual bool isTypedef() const =0
virtual bool hasCallGraph() const =0
virtual const FileDef * getFileDef() const =0
virtual bool isStrongEnumValue() const =0
virtual bool hasInlineSource() const =0
virtual bool hasEnumValues() const =0
virtual const NamespaceDef * getNamespaceDef() const =0
virtual bool hasCallerGraph() const =0
virtual void setMemberGroup(MemberGroup *grp)=0
virtual bool isEnumerate() const =0
virtual bool hasReferencedByRelation() const =0
virtual DString typeString() const =0
virtual void overrideReferencesRelation(bool e)=0
virtual void overrideReferencedByRelation(bool e)=0
virtual void overrideCallGraph(bool e)=0
virtual void overrideInlineSource(bool e)=0
virtual void overrideEnumValues(bool e)=0
virtual void overrideCallerGraph(bool e)=0
A class representing a group of members.
void insertMember(MemberDef *md)
A list of MemberDef objects as shown in documentation sections.
MemberListContainer container() const
Wrapper class for the MemberListType type.
constexpr bool isPrivate() const noexcept
constexpr MemberListType toPublic() const noexcept
static constexpr MemberListType Invalid() noexcept
constexpr MemberListType toProtected() const noexcept
constexpr bool isProtected() const noexcept
ML_TYPES constexpr bool isPublic() const noexcept
Ordered dictionary of MemberName objects.
void remove(const MemberDef *md)
static ModuleManager & instance()
An abstract interface of a namespace symbol.
Class representing a list of different code generators.
void add(OutputCodeIntfPtr &&p)
Class representing a list of output generators that are written to in parallel.
void parseText(const DString &textStr)
void disable(OutputType o)
void writeObjectLink(const DString &ref, const DString &file, const DString &anchor, const DString &name)
void startConstraintList(const DString &header)
void startConstraintParam()
void writeString(const DString &text)
void startConstraintDocs()
void startConstraintType()
void pushGeneratorState()
void disableAllBut(OutputType o)
void endConstraintParam()
void generateDoc(const DString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const DString &docStr, const DocOptions &options)
A model of a page symbol.
virtual void setTitle(const DString &title)=0
virtual void setNestingLevel(int)=0
virtual bool hasTitle() const =0
virtual void setFileName(const DString &name)=0
virtual void setShowLineNo(bool)=0
virtual DString title() const =0
virtual void setPageScope(Definition *)=0
virtual const GroupDef * getGroupDef() const =0
DString getParserName(const DString &extension)
Gets the name of the parser associated with given extension.
This struct represents an item in the list of references.
class that provide information about a section.
void setTitle(const DString &t)
Definition * definition() const
SectionInfo * replace(const DString &label, const DString &fileName, int lineNr, const DString &title, SectionType type, int level, const DString &ref=DString())
SectionInfo * add(const SectionInfo &si)
static SectionManager & instance()
returns a reference to the singleton
static constexpr int Page
const VectorPtr & find(const DString &name)
int isAccessibleFrom(const Definition *scope, const Definition *item)
Checks if symbol item is accessible from within scope.
const ClassDef * resolveClass(const Definition *scope, const DString &name, bool maybeUnlinkable=false, bool mayBeHidden=false)
Find the class definition matching name within the scope set.
const Definition * resolveSymbol(const Definition *scope, const DString &name, const DString &args=DString(), bool checkCV=false, bool insideCode=false, bool onlyLinkable=false)
Find the symbool definition matching name within the scope set.
DString getResolvedType() const
In case a call to resolveClass() points to a typedef or using declaration.
int isAccessibleFromWithExpScope(const Definition *scope, const Definition *item, const DString &explicitScopePart)
Check if symbol item is accessible from within scope, where it has to match the explicitScopePart.
DString getTemplateSpec() const
In case a call to resolveClass() points to a template specialization, the template part is return via...
void setFileScope(const FileDef *fd)
Sets or updates the file scope using when resolving symbols.
const MemberDef * getTypedef() const
In case a call to resolveClass() resolves to a type member (e.g. an enum) this method will return it.
Concrete visitor implementation for TEXT output.
TextGeneratorOLImpl(OutputList &ol)
Text streaming class that buffers data.
std::string str() const
Return the contents of the buffer as a std::string object.
virtual DString trTypeConstraints()=0
virtual DString trModule(bool first_capital, bool singular)=0
virtual DString trWriteList(int numEntries)=0
ClassDef * getClass(const DString &n)
ClassDef * toClassDef(Definition *d)
std::vector< BaseClassDef > BaseClassList
Class representing a regular expression.
@ Wildcard
simple globbing pattern.
Class to iterate through matches.
ConceptDef * getConcept(const DString &n)
ConceptDef * toConceptDef(Definition *d)
#define Config_getInt(name)
#define Config_getList(name)
#define Config_getEnumAsString(name)
#define Config_getBool(name)
#define Config_getString(name)
#define Config_getEnum(name)
std::unordered_set< std::string > StringUnorderedSet
std::vector< std::string > StringVector
DString formatDateTime(const DString &format, const std::tm &dt, int &formatUsed)
Return a string representation for a given std::tm value that is formatted according to the pattern g...
DString dateTimeFromString(const DString &spec, std::tm &dt, int &format)
Returns the filled in std::tm for a given string representing a date and/or time.
std::unique_ptr< ArgumentList > stringToArgumentList(SrcLangExt lang, const DString &argsString, DString *extraTypeChars=nullptr)
DirIterator end(const DirIterator &) noexcept
static constexpr auto hex
#define AUTO_TRACE_ADD(...)
#define AUTO_TRACE_EXIT(...)
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
IDocNodeASTPtr validatingParseTitle(IDocParser &parserIntf, const DString &fileName, int lineNr, const DString &input)
IDocParserPtr createDocParser()
factory function to create a parser
IDocNodeASTPtr validatingParseDoc(IDocParser &parserIntf, const DString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const DString &input, const DocOptions &options)
DString substitute(const DString &s, const DString &src, const DString &dst)
substitute all occurrences of src in s by dst
int dstricmp(const char *s1, const char *s2)
int dstrncmp(const char *str1, const char *str2, size_t len)
uint32_t dstrlen(const char *str)
Returns the length of string str, or 0 if a null pointer is passed.
const char * qPrint(const char *s)
bool isId(int c)
Returns true if c is a valid character for an identifier.
FileDef * toFileDef(Definition *d)
Translator * theTranslator
void linkifyText(const TextGeneratorIntf &out, const DString &text, const LinkifyTextOptions &options)
DString md5str(const std::string_view &str)
std::array< uint8_t, 16 > md5hash(const std::string_view &str)
MemberDefMutable * toMemberDefMutable(Definition *d)
MemberDef * toMemberDef(Definition *d)
#define warn(file, line, fmt,...)
ModuleDef * toModuleDef(Definition *d)
FILE * popen(const DString &name, const DString &type)
std::ifstream openInputStream(const DString &name, bool binary=false, bool openAtEnd=false)
bool fileSystemIsCaseSensitive()
std::ofstream openOutputStream(const DString &name, bool append=false)
void replaceNamespaceAliases(DString &name)
NamespaceDef * getResolvedNamespace(const DString &name)
NamespaceDef * toNamespaceDef(Definition *d)
std::string replace(std::string_view str, const Ex &re, std::string_view replacement)
Searching in a given input string for parts that match regular expression re and replaces those parts...
bool match(std::string_view str, Match &match, const Ex &re)
Matches a given string str for a match against regular expression re.
Token literal values and constants.
std::unique_ptr< PageDef > createPageDef(const DString &f, int l, const DString &n, const DString &d, const DString &t)
Portable versions of functions that are platform dependent.
int portable_iconv_close(void *cd)
size_t portable_iconv(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
void * portable_iconv_open(const char *tocode, const char *fromcode)
std::vector< RefItem * > RefItemVector
Web server based search engine.
Some helper functions for std::string.
void addTerminalCharIfMissing(std::string &s, char c)
bool literal_at(const char *data, const char(&str)[N])
returns true iff data points to a substring that matches string literal str
This class contains the information about the argument of a function or template.
Helper class to pass options when calling OutputList::generateDoc().
This struct is used to capture the tag file information for an Entry.
int isUTF8NonBreakableSpace(const char *input)
Check if the first character pointed at by input is a non-breakable whitespace character.
uint8_t getUTF8CharNumBytes(char c)
Returns the number of bytes making up a single UTF8 character given the first byte in the sequence.
Various UTF8 related helper functions.
DString stripExtension(const DString &fName)
bool useCaseSenseNames()
Returns true if the names of the symbols can be case sensitive.
bool isURL(const DString &url)
Checks whether the given url starts with a supported protocol.
DString substituteTemplateArgumentsInString(const DString &nm, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
DString parseCommentAsText(const Definition *scope, const MemberDef *md, const DString &doc, const DString &fileName, int lineNr)
static DString extractDirection(DString &docs)
Strip the direction part from docs and return it as a string in canonical form.
size_t updateColumnCount(const char *s, size_t col)
static size_t findParameterList(const DString &name)
Returns the position in the string where a function parameter list begins, or DString::npos if one is...
static std::mutex writeFileContents_lock
DString inlineArgListToDoc(const ArgumentList &al)
bool findAndRemoveWord(DString &sentence, const char *word)
removes occurrences of whole word from sentence, while keeps internal spaces and reducing multiple se...
DString stripLeadingAndTrailingEmptyLines(const DString &s, int &docLine)
Special version of DString::stripWhiteSpace() that only strips completely blank lines.
DString replaceColorMarkers(const DString &str)
Replaces any markers of the form ##AA in input string str by new markers of the form #AABBCC,...
bool protectionLevelVisible(Protection prot)
DString stripFromIncludePath(const DString &path)
DString mergeScopes(const DString &leftScope, const DString &rightScope)
bool resolveLink(const DString &scName, const DString &lr, bool, const Definition **resContext, DString &resAnchor, SrcLangExt lang, const DString &prefix)
DString filterTitle(const DString &title)
DString detab(const DString &s, size_t &refIndent)
DString selectBlocks(const DString &s, const SelectionBlockList &blockList, const SelectionMarkerInfo &markerInfo)
remove disabled blocks and all block markers from s and return the result as a string
bool matchTemplateArguments(const ArgumentList &srcAl, const ArgumentList &dstAl)
void stripIndentationVerbatim(DString &doc, size_t indentationLevel, bool skipFirstLine)
void addCodeOnlyMappings()
static int g_usedNamesCount
static void filterCRLF(std::string &contents)
static void stripIrrelevantString(DString &target, const DString &str, bool insideTemplate)
static DString stripDeclKeywords(const DString &s)
PageDef * addRelatedPage(const DString &name, const DString &ptitle, const DString &doc, const DString &fileName, int docLine, int startLine, const RefItemVector &sli, GroupDef *gd, const TagInfo *tagInfo, bool xref, SrcLangExt lang)
void writeTypeConstraints(OutputList &ol, const Definition *d, const ArgumentList &al)
DString extractBeginRawStringDelimiter(const char *rawStart)
void stripIrrelevantConstVolatile(DString &s, bool insideTemplate)
static DString getFilterFromList(const DString &name, const StringVector &filterList, bool &found)
static DString extractCanonicalArgType(const Definition *d, const FileDef *fs, const Argument &arg, SrcLangExt lang)
static DString getCanonicalTemplateSpec(const Definition *d, const FileDef *fs, const DString &spec, SrcLangExt lang)
DString writeInlineGraph(const DString &baseName, const DString &extension, const DString &content, bool &exists)
bool rightScopeMatch(const DString &scope, const DString &name)
bool checkIfTypedef(const Definition *scope, const FileDef *fileScope, const DString &n)
static const char constScope[]
static bool recursivelyAddGroupListToTitle(OutputList &ol, const Definition *d, bool root)
DString unescapeCharsInString(const DString &s)
bool resolveRef(const DString &scName, const DString &name, bool inSeeBlock, const Definition **resContext, const MemberDef **resMember, SrcLangExt lang, bool lookForSpecialization, const FileDef *currentFile, bool checkScope)
DString externalLinkTarget(const bool parent)
DString replaceAnonymousScopes(const DString &s, const DString &replacement)
void addRefItem(const RefItemVector &sli, const DString &key, const DString &prefix, const DString &name, const DString &title, const DString &args, const Definition *scope)
void cleanupInlineGraphs()
DString correctURL(const DString &url, const DString &relPath)
Corrects URL url according to the relative path relPath.
int computeQualifiedIndex(const DString &name)
Return the index of the last :: in the string name that is still before the first <.
DString convertToJSString(const DString &s, bool keepEntities, bool singleQuotes)
DString convertToId(const DString &s)
void trimBaseClassScope(const BaseClassList &bcl, DString &s, int level=0)
bool transcodeCharacterStringToUTF8(std::string &input, const char *inputEncoding)
bool recognizeFixedForm(const DString &contents, FortranFormat format)
bool patternMatch(const FileInfo &fi, const StringVector &patList)
DString insertTemplateSpecifierInScope(const DString &scope, const DString &templ)
DString removeRedundantWhiteSpace(const DString &s)
static std::unordered_map< std::string, SrcLangExt > g_extLookup
bool checkExtension(const DString &fName, const DString &ext)
int lineBlock(const DString &text, const DString &marker)
Returns the line number of the line following the line with the marker.
DString convertNameToFile(const DString &name, bool allowDots, bool allowUnderscore)
DString showDate(const DString &fmt)
void addMembersToMemberGroup(MemberList *ml, MemberGroupList *pMemberGroups, const Definition *context)
bool leftScopeMatch(const DString &scope, const DString &name)
DString stripExtensionGeneral(const DString &fName, const DString &ext)
DString tempArgListToString(const ArgumentList &al, SrcLangExt lang, bool includeDefault)
static ModuleDef * findModuleDef(const Definition *d)
DString externalRef(const DString &relPath, const DString &ref, bool href)
void addGroupListToTitle(OutputList &ol, const Definition *d)
DString extractEndRawStringDelimiter(const char *rawEnd)
static DString extractCanonicalType(const Definition *d, const FileDef *fs, DString type, SrcLangExt lang, bool insideTemplate)
void clearSubDirs(const Dir &d)
DString stripScope(const DString &name)
DString getFileNameExtension(const DString &fn)
void createSubDirs(const Dir &d)
DString convertToHtml(const DString &s, bool keepEntities)
bool fileVisibleInIndex(const FileDef *fd, bool &genSourceFile)
DString resolveTypeDef(const Definition *context, const DString &qualifiedName, const Definition **typedefContext)
DString parseCommentAsHtml(const Definition *scope, const MemberDef *member, const DString &doc, const DString &fileName, int lineNr)
bool readInputFile(const DString &fileName, std::string &contents, bool filter, bool isSourceCode)
read a file name fileName and optionally filter and transcode it
DString normalizeNonTemplateArgumentsInString(const DString &name, const Definition *context, const ArgumentList &formalArgs)
SrcLangExt getLanguageFromFileName(const DString &fileName, SrcLangExt defLang)
DString getFileFilter(const DString &name, bool isSourceCode)
bool matchArguments2(const Definition *srcScope, const FileDef *srcFileScope, const DString &srcReturnType, const ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, const DString &dstReturnType, const ArgumentList *dstAl, bool checkCV, SrcLangExt lang)
static MemberDef * getMemberFromSymbol(const Definition *scope, const FileDef *fileScope, const DString &n)
void initDefaultExtensionMapping()
void addHtmlExtensionIfMissing(DString &fName)
void checkBlocks(const DString &s, const DString fileName, const SelectionMarkerInfo &markerInfo)
DString createHtmlUrl(const DString &relPath, const DString &ref, bool href, bool isLocalFile, const DString &targetFileName, const DString &anchor)
static void transcodeCharacterBuffer(const DString &fileName, std::string &contents, const DString &inputEncoding, const DString &outputEncoding)
DString fileToString(const DString &name, bool filter, bool isSourceCode)
static const char virtualScope[]
DString linkToText(SrcLangExt lang, const DString &link, bool ignoreDots)
DString substituteKeywords(const DString &file, const DString &s, const KeywordSubstitutionList &keywords)
DString removeLongPathMarker(const DString &path)
void extractNamespaceName(const DString &scopeName, DString &className, DString &namespaceName, bool allowEmptyClass)
DString convertToXML(const DString &s, bool keepEntities, const bool citeEntry)
DString stripTemplateSpecifiersFromScope(const DString &fullName, bool parentOnly, DString *pLastScopeStripped, DString scopeName, bool allowArtificial)
static std::unordered_map< std::string, DString > g_docCache
DString relativePathToRoot(const DString &name)
static const DirDef * resolveDirLink(const DString &linkRef)
DString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
DString projectLogoFile()
static StringUnorderedSet writeFileContents_set
void convertProtectionLevel(MemberListType inListType, Protection inProt, MemberListType *outListType1, MemberListType *outListType2)
Computes for a given list type inListType, which are the the corresponding list type(s) in the base c...
static const char volatileScope[]
static int nextUTF8CharPosition(const DString &utf8Str, uint32_t len, uint32_t startPos)
DString getEncoding(const FileInfo &fi)
bool copyFile(const DString &src, const DString &dest)
Copies the contents of file with name src to the newly created file with name dest.
int getPrefixIndex(const DString &name)
DString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
bool updateLanguageMapping(const DString &extension, const DString &language)
DString demangleCSharpGenericName(const DString &name, const DString &templArgs)
void mergeMemberOverrideOptions(MemberDefMutable *md1, MemberDefMutable *md2)
DString projectLogoSize()
static DString getCanonicalTypeForIdentifier(const Definition *d, const FileDef *fs, const DString &word, SrcLangExt lang, DString *tSpec, int count=0)
DString mangleCSharpGenericName(const DString &name)
FortranFormat convertFileNameFortranParserCode(DString fn)
GetDefResult getDefs(const GetDefInput &input)
DString getDotImageExtension()
DString escapeCharsInString(const DString &name, bool allowDots, bool allowUnderscore)
static std::mutex g_usedNamesMutex
static bool matchArgument2(const Definition *srcScope, const FileDef *srcFileScope, Argument &srcA, const Definition *dstScope, const FileDef *dstFileScope, Argument &dstA, SrcLangExt lang)
void mergeArguments(ArgumentList &srcAl, ArgumentList &dstAl, bool forceNameOverwrite)
int getScopeFragment(const DString &s, int p, int *l)
static bool getScopeDefs(const DString &docScope, const DString &scope, ClassDef *&cd, ConceptDef *&cnd, NamespaceDef *&nd, ModuleDef *&modd)
DString stripIndentation(const DString &s, bool skipFirstLine)
static bool matchCanonicalTypes(const Definition *srcScope, const FileDef *srcFileScope, const DString &srcType, const Definition *dstScope, const FileDef *dstFileScope, const DString &dstType, SrcLangExt lang)
int extractClassNameFromType(const DString &type, int &pos, DString &name, DString &templSpec, SrcLangExt lang)
DString determineAbsoluteIncludeName(const DString &curFile, const DString &incFileName)
static std::mutex g_docCacheMutex
static bool keyWordsFortranC(const char *contents)
DString removeAnonymousScopes(const DString &str)
bool genericPatternMatch(const FileInfo &fi, const PatternList &patList, PatternElem &elem, PatternGet getter)
DString makeBaseName(const DString &name, const DString &ext)
void writeMarkerList(OutputList &ol, const std::string &markerText, size_t numMarkers, std::function< void(size_t)> replaceFunc)
static bool isLowerCase(DString &s)
DString stripPath(const DString &s)
static std::unordered_map< std::string, int > g_usedNames
DString stripFromPath(const DString &path)
static CharAroundSpace g_charAroundSpace
DString inlineTemplateArgListToDoc(const ArgumentList &al)
void writeExamples(OutputList &ol, const ExampleList &list)
static std::mutex g_matchArgsMutex
static const char operatorScope[]
bool openOutputFile(const DString &outFile, std::ofstream &f)
static std::vector< Lang2ExtMap > g_lang2extMap
DString stripAnonymousNamespaceScope(const DString &s)
DString findExampleFilePath(const DString &file, bool &ambig)
SrcLangExt getLanguageFromCodeLang(DString &fileName)
Routine to handle the language attribute of the \code command.
A bunch of utility functions.
std::vector< KeywordSubstitution > KeywordSubstitutionList
std::vector< SelectionBlock > SelectionBlockList