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";
108 if (s.empty())
return;
116 m_ol.writeNonBreakableSpace(1);
120 m_ol.docify(std::string_view(&c, 1));
132 m_ol.lineBreak(
"typebreak");
133 for (
int i = 0; i < indent; ++i)
m_ol.writeNonBreakableSpace(3);
137 const QCString &anchor,std::string_view text
141 m_ol.writeObjectLink(extRef,file,anchor,text);
164 if (str.
isEmpty())
return result;
167 auto startsWithColon = [](
const std::string &del)
169 for (
size_t i=0;i<del.size();i++)
171 if (del[i]==
'@')
return false;
172 else if (del[i]==
':')
return true;
178 auto endsWithColon = [](
const std::string &del)
180 for (
int i=
static_cast<int>(del.size())-1;i>=0;i--)
182 if (del[i]==
'@')
return false;
183 else if (del[i]==
':')
return true;
188 static const reg::Ex re(R
"([\s:]*@\d+[\s:]*)");
189 std::string s = str.str();
193 size_t sl=s.length();
194 bool needsSeparator=
false;
195 for ( ; iter!=
end ; ++iter)
197 const auto &match = *iter;
198 size_t i = match.position();
201 if (needsSeparator) result+=
"::";
202 needsSeparator=
false;
203 result+=s.substr(p,i-p);
205 std::string delim = match.str();
206 needsSeparator = needsSeparator || (startsWithColon(delim) && endsWithColon(delim));
207 p = match.position()+match.length();
211 if (needsSeparator) result+=
"::";
221 static const reg::Ex marker(R
"(@\d+)");
223 !replacement.isEmpty() ? replacement.data() : "__anonymous__");
234 int sl =
static_cast<int>(s.
length());
242 if (!newScope.
isEmpty()) newScope+=
"::";
243 newScope+=s.
mid(i,l);
248 if (!newScope.
isEmpty()) newScope+=
"::";
249 newScope+=s.
right(sl-i);
281 const int maxMarkerStrLen = 20;
282 char result[maxMarkerStrLen];
283 qsnprintf(result,maxMarkerStrLen,
"@%d",
id);
304 for (
const auto &s : l)
307 if (
prefix.length() > length &&
314 if (length>0)
return potential;
341 static const std::unordered_set<std::string> sourceExt = {
342 "c",
"cc",
"cxx",
"cpp",
"c++",
"cppm",
"ccm",
"cxxm",
"c++m",
346 "ii",
"ixx",
"ipp",
"i++",
"inl",
349 static const std::unordered_set<std::string> headerExt = {
350 "h",
"hh",
"hxx",
"hpp",
"h++",
"ixx",
351 "idl",
"ddl",
"pidl",
"ice"
357 if (sourceExt.find(extension.
str())!=sourceExt.end())
359 return EntryType::makeSource();
361 if (headerExt.find(extension.
str())!=headerExt.end())
363 return EntryType::makeHeader();
370 return EntryType::makeEmpty();
376 AUTO_TRACE(
"context='{}' qualifiedName='{}'",context?context->
name():
"",qualifiedName);
385 if (typedefContext) *typedefContext=context;
388 if (qualifiedName.
find(
'<')!=-1)
393 int scopeIndex = qualifiedName.
findRev(
"::");
397 resName=qualifiedName.
right(qualifiedName.
length()-scopeIndex-2);
405 while (mContext && md==
nullptr)
421 if (!tmp.
isEmpty()) qualScopePart=tmp;
424 if (resScope==
nullptr)
break;
436 bool searchRelated=
false;
437 bool mustBeRelated=
false;
448 if (mn==0 && searchRelated)
456 for (
const auto &tmd_p : *mn)
459 AUTO_TRACE_ADD(
"found candidate member '{}' isTypeDef={}' isRelated={} mustBeRelated={}",
474 if (dist!=-1 && (md==
nullptr || dist<minDist))
496 if (args.
find(
")(")!=-1)
500 else if (args.
find(
'[')!=-1)
520static const char constScope[] = {
'c',
'o',
'n',
's',
't',
':' };
521static const char volatileScope[] = {
'v',
'o',
'l',
'a',
't',
'i',
'l',
'e',
':' };
522static const char virtualScope[] = {
'v',
'i',
'r',
't',
'u',
'a',
'l',
':' };
523static const char operatorScope[] = {
'o',
'p',
'e',
'r',
'a',
't',
'o',
'r',
'?',
'?',
'?' };
579 if (s.
length()*3>growBufLen)
581 growBufLen = s.
length()*3;
582 growBuf =
static_cast<char *
>(realloc(growBuf,growBufLen+1));
584 if (growBuf==
nullptr)
return s;
586 const char *src=s.
data();
597 while (i<l && isspace(
static_cast<uint8_t
>(src[i])))
604 char nc=i+1<l ? src[i+1] :
' ';
606 auto searchForKeyword = [&](
const char *kw,
size_t &matchLen,
size_t totalLen)
608 if (matchLen<=totalLen && c==kw[matchLen] &&
643 if (c==
'\\' && i+1<l)
667 if (i>0 && !isspace(
static_cast<uint8_t
>(pc)) &&
668 (
isId(pc) || pc==
'*' || pc==
'&' || pc==
'.' || pc==
'>') &&
669 (osp<8 || (osp==8 && pc!=
'-'))
675 if (i+1<l && (nc==
'-' || nc==
'&'))
682 if (i>0 && !isspace(
static_cast<uint8_t
>(pc)) &&
683 ((i+1<l && (
isId(nc) || nc==
'[')) ||
684 (i+2<l && nc==
'$' &&
isId(src[i+2])) ||
685 (i+3<l && nc==
'&' && src[i+2]==
'$' &&
isId(src[i+3]))
695 if (cliSupport && i+1<l && (
isId(nc) || nc==
'-'))
702 if (i+1<l && (
isId(nc) || nc==
'-'))
708 if (i>0 && pc!=
' ' && pc!=
'\t' && pc!=
':' &&
709 pc!=
'*' && pc!=
'&' && pc!=
'(' && pc!=
'/' && pc!=
'[' &&
719 if (i>0 &&
isId(pc) && osp<9)
739 if (i>0 && i+1<l && pc!=
'=' && pc!=
':' && !isspace(
static_cast<uint8_t
>(pc)) &&
770 !(pc==
',' && nc==
'.') &&
771 (osp<8 || (osp>=8 &&
isId(pc) &&
isId(nc)))
779 else if ((pc==
'*' || pc==
'&' || pc==
'.') && nc==
'>')
787 auto correctKeywordAllowedInsideScope = [&](
char cc,
size_t &matchLen,
size_t totalLen) {
788 if (c==cc && matchLen==totalLen)
790 if ((i+2<l && src[i+1] ==
':' && src[i+2] ==
':') ||
791 ((i>matchLen && src[i-matchLen] ==
':' && src[i-matchLen-1] ==
':'))
795 correctKeywordAllowedInsideScope(
't',csp, 5);
796 correctKeywordAllowedInsideScope(
'e',vosp,8);
797 correctKeywordAllowedInsideScope(
'l',vsp, 7);
799 auto correctKeywordNotPartOfScope = [&](
char cc,
size_t &matchLen,
size_t totalLen)
801 if (c==cc && matchLen==totalLen && i+1<l &&
809 correctKeywordNotPartOfScope(
't',csp, 5);
810 correctKeywordNotPartOfScope(
'e',vosp,8);
811 correctKeywordNotPartOfScope(
'l',vsp, 7);
831 if (templateDepth > 0)
833 int nextOpenPos=name.
findRev(
'>', pos);
834 int nextClosePos=name.
findRev(
'<', pos);
835 if (nextOpenPos!=-1 && nextOpenPos>nextClosePos)
840 else if (nextClosePos!=-1)
852 int lastAnglePos=name.
findRev(
'>', pos);
853 int bracePos=name.
findRev(
'(', pos);
854 if (lastAnglePos!=-1 && lastAnglePos>bracePos)
861 int bp = bracePos>0 ? name.
findRev(
'(',bracePos-1) : -1;
863 return bp==-1 || (bp>=8 && name.
mid(bp-8,10)==
"operator()") ? bracePos : bp;
874 return (name==scope ||
875 (scope.
right(nl)==name &&
876 sl>1+nl && scope.
at(sl-nl-1)==
':' && scope.
at(sl-nl-2)==
':'
885 return (name==scope ||
886 (name.
left(sl)==scope &&
887 nl>sl+1 && name.
at(sl)==
':' && name.
at(sl+1)==
':'
899 AUTO_TRACE(
"scope={} fileScope={} text={} autoBreak={} external={} keepSpaces={} indentLevel={}",
900 scope?scope->
name():
"",fileScope?fileScope->
name():
"",
905 std::string_view txtStr=text.
view();
906 size_t strLen = txtStr.length();
907 if (strLen==0)
return;
909 static const reg::Ex regExp(R
"((::)?\a[\w~!\\.:$"]*)");
919 size_t floatingIndex=0;
920 for (; it!=
end ; ++it)
922 const auto &match = *it;
923 size_t newIndex = match.position();
924 size_t matchLen = match.length();
925 floatingIndex+=newIndex-skipIndex+matchLen;
926 if (newIndex>0 && txtStr.at(newIndex-1)==
'0')
928 std::string_view part = txtStr.substr(skipIndex,newIndex+matchLen-skipIndex);
930 skipIndex=index=newIndex+matchLen;
935 bool insideString=
FALSE;
936 for (
size_t i=index;i<newIndex;i++)
938 if (txtStr.at(i)==
'"') insideString=!insideString;
939 if (txtStr.at(i)==
'\\') i++;
946 std::string_view splitText = txtStr.substr(skipIndex,newIndex-skipIndex);
947 size_t splitLength = splitText.length();
949 size_t i = splitText.find(
',');
950 if (i==std::string::npos) { i=splitText.find(
'<');
if (i!=std::string::npos) offset=0; }
951 if (i==std::string::npos) { i=splitText.find(
"||");
if (i!=std::string::npos) offset=2; }
952 if (i==std::string::npos) { i=splitText.find(
"&&");
if (i!=std::string::npos) offset=2; }
953 if (i==std::string::npos) { i=splitText.find(
">>");
if (i!=std::string::npos) offset=2; }
954 if (i==std::string::npos) i=splitText.find(
'>');
955 if (i==std::string::npos) i=splitText.find(
' ');
957 if (i!=std::string::npos)
959 std::string_view part1 = splitText.substr(0,i+offset);
962 std::string_view part2 = splitText.substr(i+offset);
964 floatingIndex=splitLength-i-offset+matchLen;
974 std::string_view part = txtStr.substr(skipIndex,newIndex-skipIndex);
978 std::string_view word=txtStr.substr(newIndex,matchLen);
986 if (it1->name == matchWord)
1021 auto writeCompoundName = [&](
const auto *cd_) {
1022 if (options.
external() ? cd_->isLinkable() : cd_->isLinkableInProject())
1027 out.
writeLink(cd_->getReference(),cd_->getOutputFileBase(),cd_->anchor(),word);
1039 writeCompoundName(cd);
1041 else if ((cd=
getClass(matchWord+
"-p")))
1043 writeCompoundName(cd);
1047 writeCompoundName(cnd);
1051 writeCompoundName(d);
1058 int m = matchWord.
findRev(
"::");
1066 scopeName=scope->
name();
1070 scopeName = matchWord.
left(m);
1071 matchWord = matchWord.
mid(m+2);
1080 if (result.
found && result.
md &&
1087 if (result.
md!=self && (self==
nullptr || result.
md->
name()!=self->
name()))
1116 skipIndex=index=newIndex+matchLen;
1120 std::string_view lastPart = txtStr.substr(skipIndex);
1125 std::function<
void(
size_t)> replaceFunc)
1127 static const reg::Ex marker(R
"(@(\d+))");
1131 for ( ; it!=
end ; ++it)
1133 const auto &match = *it;
1134 size_t newIndex = match.position();
1135 size_t matchLen = match.length();
1136 ol.
parseText(markerText.substr(index,newIndex-index));
1137 unsigned long entryIndex = std::stoul(match[1].str());
1138 if (entryIndex<
static_cast<unsigned long>(numMarkers))
1140 replaceFunc(entryIndex);
1142 index=newIndex+matchLen;
1148 std::function<
QCString(
size_t)> replaceFunc)
1151 static const reg::Ex marker(R
"(@(\d+))");
1155 for ( ; it!=
end ; ++it)
1157 const auto &match = *it;
1158 size_t newIndex = match.position();
1159 size_t matchLen = match.length();
1160 result += markerText.substr(index,newIndex-index);
1161 unsigned long entryIndex = std::stoul(match[1].str());
1162 if (entryIndex<
static_cast<unsigned long>(numMarkers))
1164 result+=replaceFunc(entryIndex);
1166 index=newIndex+matchLen;
1168 if (index<markerText.size())
1170 result += markerText.substr(index);
1177 auto replaceFunc = [&list,&ol](
size_t entryIndex)
1179 const auto &e = list[entryIndex];
1211 if (a.hasDocumentation(
true))
1220 paramDocs+=
" \\ilinebr @param"+direction+
" "+name+
" "+docsWithoutDir;
1234 if (!a.docs.isEmpty())
1236 if (!a.name.isEmpty())
1238 paramDocs+=
" \\ilinebr @tparam "+a.name+
" "+a.docs;
1240 else if (!a.type.isEmpty())
1246 paramDocs+=
" \\ilinebr @tparam "+type+
" "+a.docs;
1259 for (
auto it = al.
begin() ; it!=al.
end() ;)
1264 int i=type1.
find(
")(");
1268 type1=type1.
left(i);
1276 result+= type1+
" "+a.
name+type2+a.
array;
1280 result+= type1+type2;
1287 if (it!=al.
end()) result+=
", ";
1302 if (al.
empty())
return result;
1305 for (
const auto &a : al)
1307 if (a.defval.isEmpty() || includeDefault)
1309 if (!first) result+=
", ";
1310 if (!a.name.isEmpty())
1312 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp)
1320 int i =
static_cast<int>(a.type.length())-1;
1321 while (i>=0 &&
isId(a.type.at(i))) i--;
1324 result+=a.type.
right(a.type.length()-i-1);
1325 if (a.type.find(
"...")!=-1)
1335 if (!a.typeConstraint.isEmpty() && lang==SrcLangExt::Java)
1337 result+=
" extends ";
1338 result+=a.typeConstraint;
1359 size_t len = contents.length();
1363 char c = contents[src++];
1367 if (src<len && contents[src] ==
'\n')
1372 else if ( c ==
'\0' && src<len-1)
1376 contents[dest++] = c;
1378 contents.resize(dest);
1385 for (
const auto &filterStr : filterList)
1388 int i_equals=fs.
find(
'=');
1395 filterPattern = filterPattern.
lower();
1396 input = input.
lower();
1403 if (filterName.
find(
' ')!=-1)
1405 filterName=
"\""+filterName+
"\"";
1425 if (name.
isEmpty())
return "";
1432 if (isSourceCode && !filterSrcList.empty())
1436 if (!found && filterName.
isEmpty())
1447 if (filterName.
length()>=2 && filterName[0]==
'"' && filterName[
static_cast<int>(filterName.
length())-1]==
'"')
1449 filterName = filterName.
mid(1,filterName.
length()-2);
1458 const char *outputEncoding =
"UTF-8";
1459 if (inputEncoding==
nullptr ||
qstricmp(inputEncoding,outputEncoding)==0)
return true;
1460 size_t inputSize=input.length();
1461 size_t outputSize=inputSize*4;
1464 if (cd==
reinterpret_cast<void *
>(-1))
1469 size_t iLeft=inputSize;
1470 size_t oLeft=outputSize;
1471 const char *inputPtr = input.data();
1472 char *outputPtr = output.
rawData();
1475 outputSize-=
static_cast<int>(oLeft);
1476 output.
resize(outputSize);
1477 output.
at(outputSize)=
'\0';
1497 bool fileOpened=
false;
1498 if (name[0]==
'-' && name[1]==0)
1500 std::string contents;
1502 while (getline(std::cin,line))
1504 contents+=line+
'\n';
1513 err(
"file '{}' not found\n",name);
1526 err(
"cannot open file '{}' for reading\n",name);
1534 for (
const auto &bcd : bcl)
1555 AUTO_TRACE(
"target='{}' str='{}'",target,str);
1556 if (target==str) { target.
clear();
return; }
1558 int l=
static_cast<int>(str.
length());
1561 while ((i=target.
find(str,p))!=-1)
1563 for (
int q=p;q<i;q++)
1565 if (target[q]==
'<') sharpCount++;
1566 else if (target[q]==
'>' && sharpCount>0) sharpCount--;
1568 bool isMatch = (i==0 || !
isId(target.
at(i-1))) &&
1569 (i+l==
static_cast<int>(target.
length()) || !
isId(target.
at(i+l))) &&
1570 !insideTemplate && sharpCount==0;
1573 int i1=target.
find(
'*',i+l);
1574 int i2=target.
find(
'&',i+l);
1575 if (i1==-1 && i2==-1)
1582 else if ((i1!=-1 && i<i1) || (i2!=-1 && i<i2))
1625 int i=s.
find(
" class ");
1626 if (i!=-1)
return s.
left(i)+s.
mid(i+6);
1627 i=s.
find(
" typename ");
1628 if (i!=-1)
return s.
left(i)+s.
mid(i+9);
1629 i=s.
find(
" union ");
1630 if (i!=-1)
return s.
left(i)+s.
mid(i+6);
1631 i=s.
find(
" struct ");
1632 if (i!=-1)
return s.
left(i)+s.
mid(i+7);
1645 if (!templSpec.
isEmpty() && templSpec.
at(0) ==
'<')
1652 templSpec = resolvedType;
1664 if (count>10)
return word;
1666 QCString symName,result,templSpec,tmpName;
1667 if (tSpec && !tSpec->
isEmpty())
1670 AUTO_TRACE(
"d='{}' fs='{}' word='{}' templSpec='{}'",d?d->
name():
"",fs?fs->
name():
"",word,templSpec);
1688 bool isTemplInst = cd && !templSpec.
isEmpty();
1689 if (!cd && !templSpec.
isEmpty())
1700 cd?cd->
name():
"",mType?mType->
name():
"",ts,resolvedType);
1723 if (cd==d && tSpec) *tSpec=
"";
1727 result = resolvedType+ts;
1735 if (tSpec) *tSpec=
"";
1749 result=cd->
name()+templSpec;
1799 resolvedType = lang==SrcLangExt::Java ? word :
resolveTypeDef(d,word);
1807 result = resolvedType;
1840 if (i>pp) canType += type.
mid(pp,i-pp);
1861 std::string ts = templSpec.
str();
1862 static const reg::Ex re(R
"(\a\w*)");
1869 for (; it!=
end ; ++it)
1871 const auto &match = *it;
1872 size_t ti = match.position();
1873 size_t tl = match.length();
1874 std::string matchStr = match.str();
1875 canType += ts.substr(tp,ti-tp);
1879 canType+=ts.substr(tp);
1895 if ((type==
"const" || type==
"volatile") && !name.
isEmpty())
1900 if (name==
"const" || name==
"volatile")
1902 if (!type.
isEmpty()) type+=
" ";
1920#define MATCH AUTO_TRACE_EXIT("match at line {}",__LINE__);
1921#define NOMATCH AUTO_TRACE_EXIT("no match at line {}",__LINE__);
1928 AUTO_TRACE(
"srcType='{}' dstType='{}'",srcType,dstType);
1929 if (srcType==dstType)
return true;
1932 int i1=srcType.
find(
")(");
1933 if (i1==-1)
return false;
1934 int i2=dstType.
find(
")(");
1935 if (i1!=i2)
return false;
1938 int j1=srcType.
find(
"(");
1939 if (j1==-1 || j1>i1)
return false;
1940 int j2=dstType.
find(
"(");
1941 if (j2!=j1)
return false;
1942 if (srcType.
left(j1)!=dstType.
left(j2))
return false;
1951 dstScope,dstFileScope,dstType.
left(j2),dstAl.get(),
1961 AUTO_TRACE(
"src: scope={} type={} name={} canType={}, dst: scope={} type={} name={} canType={}",
1980 srcA.
type+=sSrcName;
1984 else if (sDstName==srcType.
right(sDstName.
length()))
1986 dstA.
type+=sDstName;
2002 dstScope,dstFileScope,dstA.
canType,
2025 ASSERT(srcScope!=
nullptr && dstScope!=
nullptr);
2027 AUTO_TRACE(
"srcScope='{}' dstScope='{}' srcArgs='{}' dstArgs='{}' checkCV={} lang={}",
2030 if (srcAl==
nullptr || dstAl==
nullptr)
2032 bool match = srcAl==dstAl;
2063 if (srcAl->
size() != dstAl->
size())
2097 auto srcIt = srcAl->
begin();
2098 auto dstIt = dstAl->
begin();
2099 for (;srcIt!=srcAl->
end() && dstIt!=dstAl->
end();++srcIt,++dstIt)
2104 dstScope,dstFileScope,dstA,
2123 AUTO_TRACE(
"srcAl='{}',dstAl='{}',forceNameOverwrite={}",
2131 auto srcIt=srcAl.
begin();
2132 auto dstIt=dstAl.
begin();
2133 while (srcIt!=srcAl.
end() && dstIt!=dstAl.
end())
2138 AUTO_TRACE_ADD(
"before merge: src=[type='{}',name='{}',def='{}'] dst=[type='{}',name='{}',def='{}']",
2154 if (srcA.
name==
"const" || srcA.
name==
"volatile")
2159 if (dstA.
name==
"const" || dstA.
name==
"volatile")
2185 if (forceNameOverwrite)
2228 j1=
static_cast<int>(srcA.
type.
length())-i1-2,
2229 j2=
static_cast<int>(dstA.
type.
length())-i2-2;
2237 else if (i1==-1 && i2!=-1 && dstA.
type.
right(j2)==srcA.
type)
2257 AUTO_TRACE_ADD(
"after merge: src=[type='{}',name='{}',def='{}'] dst=[type='{}',name='{}',def='{}']",
2273 auto isUnconstraintTemplate = [](
const QCString &type)
2275 return type==
"typename" || type==
"class" || type.startsWith(
"typename ") || type.startsWith(
"class ");
2277 auto srcIt = srcAl.
begin();
2278 auto dstIt = dstAl.
begin();
2279 while (srcIt!=srcAl.
end() && dstIt!=dstAl.
end())
2283 if ((!isUnconstraintTemplate(srcA.
type) || !isUnconstraintTemplate(dstA.
type)) && srcA.
type!=dstA.
type)
2302 AUTO_TRACE(
"scopeName={},memberName={},forceEmptyScope={}",
2328 result.
found =
true;
2333 result.
found =
true;
2338 result.
found =
true;
2343 result.
found =
true;
2348 result.
found =
true;
2380 bool explicitGlobalScope=
FALSE;
2381 if (scopeName.
at(0)==
':' && scopeName.
at(1)==
':')
2384 explicitGlobalScope=
TRUE;
2392 int scopeOffset=explicitGlobalScope ? 0 :
static_cast<int>(docScopeName.
length());
2397 if (scopeOffset>0) fullName.
prepend(docScopeName.
left(scopeOffset)+
"::");
2421 else if ((scopeOffset=docScopeName.
findRev(
"::",scopeOffset-1))==-1)
2425 }
while (scopeOffset>=0);
2433 const char *p=s.
data();
2435 while ((c=
static_cast<uint8_t
>(*p++)))
if (!islower(c))
return false;
2448 bool lookForSpecialization,
2453 AUTO_TRACE(
"scope={} name={} inSeeBlock={} lang={} lookForSpecialization={} currentFile={} checkScope={}",
2454 scName,name,inSeeBlock,lang,lookForSpecialization,currentFile ? currentFile->
name() :
"", checkScope);
2459 if (fullName.
find(
"anonymous_namespace{")==-1)
2469 if (lang==SrcLangExt::CSharp && (templStartPos=fullName.
find(
'<'))!=-1)
2471 int templEndPos = fullName.
findRev(
'>');
2472 if (templEndPos!=-1)
2480 int endNamePos=bracePos!=-1 ? bracePos :
static_cast<int>(fullName.
length());
2481 int scopePos=fullName.
findRev(
"::",endNamePos);
2482 bool explicitScope = fullName.
startsWith(
"::") &&
2487 bool allowTypeOnly=
false;
2490 *resContext=
nullptr;
2497 if (!inSeeBlock && scopePos==-1 &&
isLowerCase(tsName))
2511 if (scName!=fullName &&
getScopeDefs(scName,fullName,cd,cnd,nd,modd))
2534 else if (scName==fullName || (!inSeeBlock && scopePos==-1))
2553 if (explicitScope) nameStr=nameStr.
mid(2);
2558 if (bracePos!=-1) argsStr=fullName.
right(fullName.
length()-bracePos);
2562 int templPos=nameStr.
find(
'<');
2563 bool tryUnspecializedVersion =
FALSE;
2564 if (templPos!=-1 && nameStr.
find(
"operator")==-1)
2566 int endTemplPos=nameStr.
findRev(
'>');
2567 if (endTemplPos!=-1)
2569 if (!lookForSpecialization)
2571 nameStr=nameStr.
left(templPos)+nameStr.
right(nameStr.
length()-endTemplPos-1);
2575 tryUnspecializedVersion =
TRUE;
2583 nameStr=nameStr.
mid(scopeStr.
length()+2);
2609 *resContext=
nullptr;
2619 *resMember=result.
md;
2620 *resContext=result.
md;
2624 *resContext=
nullptr;
2630 else if (result.
cd) *resContext=result.
cd;
2631 else if (result.
nd) *resContext=result.
nd;
2632 else if (result.
fd) *resContext=result.
fd;
2633 else if (result.
gd) *resContext=result.
gd;
2634 else if (result.
cnd) *resContext=result.
cnd;
2635 else if (result.
modd) *resContext=result.
modd;
2638 *resContext=
nullptr; *resMember=
nullptr;
2665 else if (tsName.
find(
'.')!=-1)
2677 if (tryUnspecializedVersion)
2679 bool b =
resolveRef(scName,name,inSeeBlock,resContext,resMember,lang,
FALSE,
nullptr,checkScope);
2707 if (!isFileName && result.
find(
'<')==-1) result=
substitute(result,
".",
"::",3);
2709 if (result.
at(0)==
':' && result.
at(1)==
':')
2733 *resContext=
nullptr;
2736 if (lang==SrcLangExt::CSharp)
2741 AUTO_TRACE(
"scName='{}',ref='{}'",scName,lr);
2746 const DirDef *dir =
nullptr;
2764 if (si) resAnchor = si->
label();
2776 resAnchor = si->
label();
2783 resAnchor = si->
label();
2813 else if (lang==SrcLangExt::Java &&
2814 (cd=
getClass(linkRefWithoutTemplates)))
2821 else if ((cd=
getClass(linkRef+
"-p")))
2838 resAnchor=modd->
anchor();
2859 if (md) resAnchor=md->
anchor();
2897 if (n.
isEmpty())
return nullptr;
2900 const int maxAddrSize = 20;
2901 char addr[maxAddrSize];
2902 qsnprintf(addr,maxAddrSize,
"%p:",
reinterpret_cast<const void*
>(fnMap));
2911 ambig = cachedResult->
isAmbig;
2922 if (name.
isEmpty())
return nullptr;
2929 if (name.
isEmpty())
return nullptr;
2936 const std::unique_ptr<FileDef> &fd = fn->front();
2938 fd->getPath().right(path.
length())==path :
2940 if (path.
isEmpty() || isSamePath)
2942 cachedResult->
fileDef = fd.get();
2951 for (
const auto &fd_p : *fn)
2955 if (fdStripPath == pathStripped)
2972 cachedResult->
isAmbig = ambig;
2973 cachedResult->
fileDef = lastMatch;
3003 for (
const auto &s : examplePathList)
3045 for (
const auto &fd_p : *fn)
3053 if (!first) result +=
"\n";
3067 std::string substRes;
3069 const char *p = s.
data();
3073 substRes.reserve(s.
length()+1024);
3080 for (
const auto &kw : keywords)
3082 size_t keyLen =
qstrlen(kw.keyword);
3083 if (
qstrncmp(p,kw.keyword,keyLen)==0)
3085 const char *startArg = p+keyLen;
3086 bool expectParam = std::holds_alternative<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
3088 if (expectParam && *startArg==
'(')
3091 const char *endArg =
nullptr;
3092 while ((c=*(startArg+j)) && c!=
')' && c!=
'\n' && c!=0) j++;
3093 if (c==
')') endArg=startArg+j;
3097 auto &&getValue = std::get<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
3098 substRes+=getValue(value).str();
3105 warn(file,line,
"Missing argument for '{}'",kw.keyword);
3109 else if (!expectParam)
3111 auto &&getValue = std::get<KeywordSubstitution::GetValue>(kw.getValueVariant);
3112 substRes+=getValue().str();
3119 warn(file,line,
"Expected arguments for '{}' but none were specified",kw.keyword);
3129 if (c==
'\n') line++;
3157 int wi = projectLogo.
find(
" width=");
3160 projectLogo = projectLogo.
left(wi);
3162 int hi = projectLogo.
find(
" height=");
3165 projectLogo = projectLogo.
left(hi);
3178 auto extractDimension = [&projectLogo](
const char *startMarker,
size_t startPos,
size_t endPos) ->
QCString
3181 if (result.
length()>=2 && result.
at(0)!=
'"' && result.
at(result.
length()-1)!=
'"')
3183 result=
"\""+result+
"\"";
3189 int wi = projectLogo.
find(
" width=");
3190 int hi = projectLogo.
find(
" height=");
3191 if (wi!=-1 && hi!=-1)
3195 sizeVal = extractDimension(
" width=", wi+7, hi) +
" "
3196 + extractDimension(
" height=", hi+8, projectLogo.
length());
3200 sizeVal = extractDimension(
" height=", hi+8, wi) +
" "
3201 + extractDimension(
" width=", wi+7, projectLogo.
length());
3206 sizeVal = extractDimension(
" width=", wi+7, projectLogo.
length());
3210 sizeVal = extractDimension(
" height=", hi+8, projectLogo.
length());
3223 {
"$title", [&]() {
return !title.
isEmpty() ? title : projName; } },
3224 {
"$doxygenversion", [&]() {
return getDoxygenVersion(); } },
3225 {
"$projectname", [&]() {
return projName; } },
3226 {
"$projectnumber", [&]() {
return projNum; } },
3227 {
"$projectbrief", [&]() {
return projBrief; } },
3231 {
"$langISO", [&]() {
return theTranslator->trISOLang(); } },
3246 for (
const auto &s : sl)
3248 const char *ps=s.c_str();
3249 const char *pd=name.
data();
3251 while (*ps!=0 && *pd!=0 && *ps==*pd)
3257 if (*ps==0 && *pd!=0)
3273int getUtf8Char(
const char *input,
char ids[MAX_UTF8_CHAR_SIZE],CaseModifier modifier)
3276 const unsigned char uc = (
unsigned char)*input;
3277 bool validUTF8Char =
false;
3280 const char* pt = input+1;
3282 if ((uc&0x80)==0x00)
3286 case CaseModifier::None: ids[0]=*input;
break;
3287 case CaseModifier::ToUpper: ids[0]=(char)toupper(*input);
break;
3288 case CaseModifier::ToLower: ids[0]=(char)tolower(*input);
break;
3295 if ((uc&0xE0)==0xC0)
3299 if ((uc&0xF0)==0xE0)
3303 if ((uc&0xF8)==0xF0)
3308 validUTF8Char = l>0;
3309 for (
int m=1; m<l && validUTF8Char; ++m)
3311 unsigned char ct = (
unsigned char)*pt;
3312 if (ct==0 || (ct&0xC0)!=0x80)
3314 validUTF8Char=
false;
3335 if (caseSenseNames == CASE_SENSE_NAMES_t::YES)
return true;
3336 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO)
return false;
3342 if (name.
isEmpty())
return name;
3348 const char *p=name.
data();
3353 case '_':
if (allowUnderscore) result+=
'_';
else result+=
"__";
break;
3354 case '-': result+=
'-';
break;
3355 case ':': result+=
"_1";
break;
3356 case '/': result+=
"_2";
break;
3357 case '<': result+=
"_3";
break;
3358 case '>': result+=
"_4";
break;
3359 case '*': result+=
"_5";
break;
3360 case '&': result+=
"_6";
break;
3361 case '|': result+=
"_7";
break;
3362 case '.':
if (allowDots) result+=
'.';
else result+=
"_8";
break;
3363 case '!': result+=
"_9";
break;
3364 case ',': result+=
"_00";
break;
3365 case ' ': result+=
"_01";
break;
3366 case '{': result+=
"_02";
break;
3367 case '}': result+=
"_03";
break;
3368 case '?': result+=
"_04";
break;
3369 case '^': result+=
"_05";
break;
3370 case '%': result+=
"_06";
break;
3371 case '(': result+=
"_07";
break;
3372 case ')': result+=
"_08";
break;
3373 case '+': result+=
"_09";
break;
3374 case '=': result+=
"_0a";
break;
3375 case '$': result+=
"_0b";
break;
3376 case '\\': result+=
"_0c";
break;
3377 case '@': result+=
"_0d";
break;
3378 case ']': result+=
"_0e";
break;
3379 case '[': result+=
"_0f";
break;
3380 case '#': result+=
"_0g";
break;
3381 case '"': result+=
"_0h";
break;
3382 case '~': result+=
"_0i";
break;
3383 case '\'': result+=
"_0j";
break;
3384 case ';': result+=
"_0k";
break;
3385 case '`': result+=
"_0l";
break;
3389 bool doEscape =
true;
3390 if (allowUnicodeNames)
3403 unsigned char id =
static_cast<unsigned char>(c);
3412 else if (caseSenseNames || !isupper(c))
3419 result+=
static_cast<char>(tolower(c));
3433 const char *p = s.
data();
3443 case '_': result+=c; p++;
break;
3444 case '1': result+=
':'; p++;
break;
3445 case '2': result+=
'/'; p++;
break;
3446 case '3': result+=
'<'; p++;
break;
3447 case '4': result+=
'>'; p++;
break;
3448 case '5': result+=
'*'; p++;
break;
3449 case '6': result+=
'&'; p++;
break;
3450 case '7': result+=
'|'; p++;
break;
3451 case '8': result+=
'.'; p++;
break;
3452 case '9': result+=
'!'; p++;
break;
3456 case '0': result+=
','; p+=2;
break;
3457 case '1': result+=
' '; p+=2;
break;
3458 case '2': result+=
'{'; p+=2;
break;
3459 case '3': result+=
'}'; p+=2;
break;
3460 case '4': result+=
'?'; p+=2;
break;
3461 case '5': result+=
'^'; p+=2;
break;
3462 case '6': result+=
'%'; p+=2;
break;
3463 case '7': result+=
'('; p+=2;
break;
3464 case '8': result+=
')'; p+=2;
break;
3465 case '9': result+=
'+'; p+=2;
break;
3466 case 'a': result+=
'='; p+=2;
break;
3467 case 'b': result+=
'$'; p+=2;
break;
3468 case 'c': result+=
'\\'; p+=2;
break;
3469 case 'd': result+=
'@'; p+=2;
break;
3470 case 'e': result+=
']'; p+=2;
break;
3471 case 'f': result+=
'['; p+=2;
break;
3472 case 'g': result+=
'#'; p+=2;
break;
3473 case 'h': result+=
'"'; p+=2;
break;
3474 case 'i': result+=
'~'; p+=2;
break;
3475 case 'j': result+=
'\''; p+=2;
break;
3476 case 'k': result+=
';'; p+=2;
break;
3477 case 'l': result+=
'`'; p+=2;
break;
3484 if (!caseSenseNames && c>=
'a' && c<=
'z')
3486 result+=
static_cast<char>(toupper(*p));
3517 if (name.
isEmpty())
return name;
3540 size_t resultLen = result.
length();
3544 uint8_t md5_sig[16];
3546 MD5Buffer(result.
data(),
static_cast<unsigned int>(resultLen),md5_sig);
3547 MD5SigToString(md5_sig,sigStr);
3548 result=result.
left(128-32)+sigStr;
3553 int l1Dir=0,l2Dir=0;
3554 int createSubdirsLevel =
Config_getInt(CREATE_SUBDIRS_LEVEL);
3555 int createSubdirsBitmaskL2 = (1<<createSubdirsLevel)-1;
3558 uint8_t md5_sig[16];
3559 MD5Buffer(result.
data(),
static_cast<unsigned int>(result.
length()),md5_sig);
3560 l1Dir = md5_sig[14] & 0xf;
3561 l2Dir = md5_sig[15] & createSubdirsBitmaskL2;
3572 const int sig_size=16;
3573 uint8_t md5_sig[sig_size];
3574 MD5Buffer(fn.
data(),
static_cast<unsigned int>(fn.
length()),md5_sig);
3575 char result[sig_size*3+2];
3578 for (
int i=0;i<sig_size;i++)
3580 static const char oct[]=
"01234567";
3581 uint8_t
byte = md5_sig[i];
3582 *p++=oct[(
byte>>6)&7];
3583 *p++=oct[(
byte>>3)&7];
3584 *p++=oct[(
byte>>0)&7];
3614 QCString absIncFileName = incFileName;
3624 else if (searchIncludes)
3627 for (
const auto &incPath : includePath)
3646 return absIncFileName;
3656 int createSubdirsLevelPow2 = 1 <<
Config_getInt(CREATE_SUBDIRS_LEVEL);
3657 for (
int l1=0; l1<16; l1++)
3663 term(
"Failed to create output directory '{}'\n",subdir);
3665 for (
int l2=0; l2<createSubdirsLevelPow2; l2++)
3668 subsubdir.
sprintf(
"d%x/d%02x",l1,l2);
3671 term(
"Failed to create output directory '{}'\n",subsubdir);
3683 int createSubdirsLevelPow2 = 1 <<
Config_getInt(CREATE_SUBDIRS_LEVEL);
3684 for (
int l1=0;l1<16;l1++)
3688 for (
int l2=0; l2 < createSubdirsLevelPow2; l2++)
3691 subsubdir.
sprintf(
"d%x/d%02x",l1,l2);
3710 bool allowEmptyClass)
3717 namespaceName=nd->
name();
3721 p=
static_cast<int>(clName.
length())-2;
3722 while (p>=0 && (i=clName.
findRev(
"::",p))!=-1)
3729 namespaceName=nd->
name();
3738 className=scopeName;
3739 namespaceName.
clear();
3742 if (className.
isEmpty() && !namespaceName.
isEmpty() && !allowEmptyClass)
3745 className=namespaceName;
3746 namespaceName.
clear();
3752 className = className.
left(className.
length()-2);
3793 int l =
static_cast<int>(result.
length());
3796 bool skipBracket=
FALSE;
3803 while (p>=0 && count>=0)
3805 char c=result.
at(p);
3811 if (p>0 && result.
at(p-1)==
':' && (count==0 || skipBracket))
3813 return result.
right(l-p-1);
3824 if (p>0 && result.
at(p-1)==
'>')
3832 bool foundMatch=
false;
3833 while (p>=0 && !foundMatch)
3845 if (round==0) count++;
3852 if (result.
at(p-1) ==
'<')
3859 foundMatch = count==0;
3874 done = count==0 || skipBracket;
3888 const char *p = s.
data();
3894 if ((c>=
'0' && c<=
'9') || (c>=
'a' && c<=
'z') || (c>=
'A' && c<=
'Z') || c==
'-')
3896 if (first && c>=
'0' && c<=
'9') result+=
'a';
3902 encChar[1]=
hex[
static_cast<unsigned char>(c)>>4];
3903 encChar[2]=
hex[
static_cast<unsigned char>(c)&0xF];
3928 const char *p = s.
data();
3934 case '<': result+=
"<";
break;
3935 case '>': result+=
">";
break;
3936 case '&':
if (keepEntities)
3942 if (ce==
';' || (!(
isId(ce) || ce==
'#')))
break;
3948 while (p<e) result+=*p++;
3960 case '\'': result+=
"'";
break;
3961 case '"': result+=
""";
break;
3962 case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
3963 case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
3964 case 19:
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
case 26:
3965 case 27:
case 28:
case 29:
case 30:
case 31:
3967 default: result+=c;
break;
3979 const char *p=s.
data();
3985 case '<': result+=
"<";
break;
3986 case '>': result+=
">";
break;
3987 case '&':
if (keepEntities)
3993 if (ce==
';' || (!(
isId(ce) || ce==
'#')))
break;
3999 while (p<e) result+=*p++;
4011 case '\'': result+=
"'";
break;
4012 case '"': result+=
""";
break;
4015 uint8_t uc =
static_cast<uint8_t
>(c);
4016 if (uc<32 && !isspace(c))
4020 result+=
hex[uc&0xF];
4039 const char *p=s.
data();
4045 case '"':
if (!singleQuotes) result+=
"\\\"";
else result+=c;
4047 case '\'':
if (singleQuotes) result+=
"\\\'";
else result+=c;
4049 case '\\':
if (*p==
'u' && *(p+1)==
'{') result+=
"\\";
4050 else result+=
"\\\\";
4052 default: result+=c;
break;
4062 std::string s = str.
data();
4063 static const reg::Ex re(R
"(&\a\w*;)");
4069 size_t p=0, i=0, l=0;
4070 for (; it!=
end ; ++it)
4072 const auto &match = *it;
4073 p = match.position();
4077 result+=s.substr(i,p-i);
4081 const char *code=
nullptr;
4092 result+=s.substr(i);
4112 ASSERT(context!=
nullptr);
4114 if (ml==
nullptr)
return;
4116 struct MoveMemberInfo
4119 : memberDef(md), memberGroup(mg), sli(rv) {}
4124 std::vector<MoveMemberInfo> movedMembers;
4126 for (
const auto &md : *ml)
4128 if (md->isEnumerate())
4130 for (
const auto &fmd : md->enumFieldList())
4132 int groupId=fmd->getMemberGroupId();
4138 const auto &info = it->second;
4139 auto mg_it = std::find_if(pMemberGroups->begin(),
4140 pMemberGroups->end(),
4141 [&groupId](
const auto &g)
4142 { return g->groupId()==groupId; }
4145 if (mg_it==pMemberGroups->end())
4147 auto mg = std::make_unique<MemberGroup>(
4156 pMemberGroups->push_back(std::move(mg));
4160 mg_ptr = (*mg_it).get();
4172 int groupId=md->getMemberGroupId();
4178 const auto &info = it->second;
4179 auto mg_it = std::find_if(pMemberGroups->begin(),
4180 pMemberGroups->end(),
4181 [&groupId](
const auto &g)
4182 { return g->groupId()==groupId; }
4185 if (mg_it==pMemberGroups->end())
4187 auto mg = std::make_unique<MemberGroup>(
4196 pMemberGroups->push_back(std::move(mg));
4200 mg_ptr = (*mg_it).get();
4202 movedMembers.emplace_back(md,mg_ptr,info->m_sli);
4208 for (
const auto &mmi : movedMembers)
4210 ml->
remove(mmi.memberDef);
4211 mmi.memberGroup->insertMember(mmi.memberDef->resolveAlias());
4212 mmi.memberGroup->setRefItems(mmi.sli);
4228 AUTO_TRACE(
"type='{}' name='{}' lang={}",type,name,lang);
4229 static const reg::Ex re_norm(R
"(\a[\w:]*)");
4230 static const reg::Ex re_fortran(R
"(\a[\w:()=]*)");
4240 size_t typeLen=type.
length();
4243 if (lang == SrcLangExt::Fortran)
4255 std::string s = type.
str();
4261 const auto &match = *it;
4262 size_t i = match.position();
4263 size_t l = match.length();
4268 while (ts<typeLen && type[
static_cast<uint32_t
>(ts)]==
' ') { ts++; tl++; }
4269 if (ts<typeLen && type[
static_cast<uint32_t
>(ts)]==
'<')
4274 while (te<typeLen && brCount!=0)
4276 if (type[
static_cast<uint32_t
>(te)]==
'<')
4278 if (te<typeLen-1 && type[
static_cast<uint32_t
>(te)+1]==
'<') te++;
else brCount++;
4280 if (type[
static_cast<uint32_t
>(te)]==
'>')
4282 if (te<typeLen-1 && type[
static_cast<uint32_t
>(te)+1]==
'>') te++;
else brCount--;
4292 pos=
static_cast<int>(i+l+tl);
4296 pos=
static_cast<int>(i+l);
4301 return static_cast<int>(i);
4304 pos =
static_cast<int>(typeLen);
4317 int p=name.
find(
'<');
4318 if (p==-1)
return name;
4322 std::string s = name.
mid(p).
str();
4323 static const reg::Ex re(R
"([\a:][\w:]*)");
4328 for (; it!=
end ; ++it)
4330 const auto &match = *it;
4331 size_t i = match.position();
4332 size_t l = match.length();
4333 result += s.substr(pi,i-pi);
4336 for (
const Argument &formArg : formalArgs)
4338 if (formArg.name == n)
4364 result+=s.substr(pi);
4382 if (formalArgs.
empty())
return nm;
4385 static const reg::Ex re(R
"(\a\w*)");
4386 std::string name = nm.str();
4391 for (; it!=
end ; ++it)
4393 const auto &match = *it;
4394 size_t i = match.position();
4395 size_t l = match.length();
4396 if (i>p) result += name.substr(p,i-p);
4401 actIt = actualArgs->
begin();
4408 for (
auto formIt = formalArgs.
begin();
4409 formIt!=formalArgs.
end() && !found;
4415 if (actualArgs && actIt!=actualArgs->
end())
4422 formArg.
type =
"class";
4427 formArg.
type =
"typename";
4431 formArg.
name +=
"...";
4436 formArg.
name +=
"...";
4443 if (formArg.
name==n && actualArgs && actIt!=actualArgs->
end() && !actArg.
type.
isEmpty())
4450 ii = subst.find(
'<');
4452 if (ii!=-1 &&
static_cast<int>(
prefix.length())>=ii+2 &&
prefix.mid(
prefix.length()-ii-2,ii+1)==subst.left(ii+1))
4457 while ((ii=subst.find(nameArg,pp))!=-1)
4459 bool beforeNonWord = ii==0 || !
isId(subst.at(ii-1));
4460 bool afterNonWord = subst.length()==ii+nameArg.length() || !
isId(subst.at(ii+nameArg.length()));
4461 if (beforeNonWord && afterNonWord)
4465 pp=ii+
static_cast<int>(nameArg.length());
4470 AUTO_TRACE_ADD(
"result={} n={} type={} hasRecursion={}",result,n,actArg.
type,hasRecursion(result,n,actArg.
type));
4471 if (!hasRecursion(result,n,actArg.
type))
4483 result += actArg.
type;
4489 result += actArg.
type+
" "+actArg.
name;
4494 else if (formArg.
name==n &&
4495 (actualArgs==
nullptr || actIt==actualArgs->
end()) &&
4504 else if (formArg.
name==n &&
4505 (actualArgs==
nullptr || actIt==actualArgs->
end()) &&
4513 if (actualArgs && actIt!=actualArgs->
end())
4524 result+=name.substr(p);
4542 bool allowArtificial)
4545 int i=fullName.
find(
'<');
4546 if (i==-1)
return fullName;
4549 int l=
static_cast<int>(fullName.
length());
4556 while (e<l && count>0)
4558 char c=fullName.
at(e++);
4561 case '(': round++;
break;
4562 case ')':
if (round>0) round--;
break;
4563 case '<':
if (round==0) count++;
break;
4564 case '>':
if (round==0) count--;
break;
4569 int si= fullName.
find(
"::",e);
4571 if (parentOnly && si==-1)
break;
4574 result+=fullName.
mid(p,i-p);
4577 if (cd!=
nullptr && (allowArtificial || !cd->
isArtificial()))
4579 result+=fullName.
mid(i,e-i);
4582 else if (pLastScopeStripped)
4585 *pLastScopeStripped=fullName.
mid(i,e-i);
4588 i=fullName.
find(
'<',p);
4590 result+=fullName.
right(l-p);
4607 AUTO_TRACE(
"leftScope='{}' rightScope='{}'",leftScope,rightScope);
4615 int i=0,p=
static_cast<int>(leftScope.
length());
4620 while ((i=leftScope.
findRev(
"::",p))>0)
4624 result = leftScope.
left(i+2)+rightScope;
4652 int sl=
static_cast<int>(s.
length());
4656 if (sp>=sl)
return -1;
4680 while (sp<sl && !done)
4686 case '<': count++;
break;
4687 case '>': count--;
if (count==0) done=
true;
break;
4720 bool newPage =
true;
4725 warn(fileName,startLine,
"multiple use of page label '{}' with different titles, (other occurrence: {}, line: {})",
4809 else if (si->
lineNr() != -1)
4811 warn(orgFile,line,
"multiple use of section label '{}', (first occurrence: {}, line {})",pd->
name(),si->
fileName(),si->
lineNr());
4815 warn(orgFile,line,
"multiple use of section label '{}', (first occurrence: {})",pd->
name(),si->
fileName());
4840 if (!key.
isEmpty() && key[0]!=
'@')
4845 item->setScope(scope);
4846 item->setName(name);
4847 item->setTitle(title);
4848 item->setArgs(args);
4849 item->setGroup(key);
4897 if (!first) { ol.
writeString(
" | "); }
else first=
false;
4909 if (!first) { ol.
writeString(
" | "); }
else first=
false;
4935 int i_fs = fName.
findRev(
'/');
4936 int i_bs = fName.
findRev(
'\\');
4937 int i = fName.
find(
'.',std::max({ i_fs, i_bs ,0}));
4965 result=result.
mid(i+1);
4970 result=result.
mid(i+1);
4983 if (str.
isEmpty() || word==
nullptr)
return false;
4984 static const reg::Ex re(R
"(\a+)");
4985 std::string s = str.str();
4988 if (it->str()==word)
return true;
4999 static reg::Ex re(R
"(\s*(<\a+>)\s*)");
5000 std::string s = sentence.str();
5006 for ( ; it!=
end ; ++it)
5008 const auto match = *it;
5009 std::string part = match[1].str();
5012 size_t i = match.position();
5013 size_t l = match.length();
5014 result+=s.substr(p,i-p);
5015 result+=match.str();
5021 size_t i = match[1].position();
5022 size_t l = match[1].length();
5023 result+=s.substr(p,i-p);
5027 result+=s.substr(p);
5043 const char *p = s.
data();
5046 int i=0,li=-1,l=
static_cast<int>(s.
length());
5050 if (c==
' ' || c==
'\t' || c==
'\r') { i++; p++; }
5051 else if (c==
'\\' &&
literal_at(p,
"\\ilinebr")) { i+=8; li=i; p+=8; }
5052 else if (c==
'\n') { i++; li=i; docLine++; p++; }
5062 if (c==
' ' || c==
'\t' || c==
'\r') { b--; p--; }
5063 else if (c==
'r' && b>=7 &&
literal_at(p-7,
"\\ilinebr")) { bi=b-7; b-=8; p-=8; }
5064 else if (c==
'>' && b>=11 &&
literal_at(p-11,
"\\ilinebr<br>")) { bi=b-11; b-=12; p-=12; }
5065 else if (c==
'\n') { bi=b; b--; p--; }
5070 if (li==-1 && bi==-1)
return s;
5077 return s.
mid(li,bi-li);
5095 {
"idl",
"c", SrcLangExt::IDL,
".idl" },
5096 {
"java",
"c", SrcLangExt::Java,
".java"},
5097 {
"javascript",
"c", SrcLangExt::JS,
".js" },
5098 {
"csharp",
"c", SrcLangExt::CSharp,
".cs" },
5099 {
"d",
"c", SrcLangExt::D,
".d" },
5100 {
"php",
"c", SrcLangExt::PHP,
".php" },
5101 {
"objective-c",
"c", SrcLangExt::ObjC,
".m" },
5102 {
"c",
"c", SrcLangExt::Cpp,
".c" },
5103 {
"c++",
"c", SrcLangExt::Cpp,
".cpp" },
5104 {
"slice",
"c", SrcLangExt::Slice,
".ice" },
5105 {
"python",
"python", SrcLangExt::Python,
".py" },
5106 {
"fortran",
"fortran", SrcLangExt::Fortran,
".f" },
5107 {
"fortranfree",
"fortranfree", SrcLangExt::Fortran,
".f90" },
5108 {
"fortranfixed",
"fortranfixed", SrcLangExt::Fortran,
".f" },
5109 {
"vhdl",
"vhdl", SrcLangExt::VHDL,
".vhdl"},
5110 {
"xml",
"xml", SrcLangExt::XML,
".xml" },
5111 {
"sql",
"sql", SrcLangExt::SQL,
".sql" },
5112 {
"md",
"md", SrcLangExt::Markdown,
".md" },
5113 {
"lex",
"lex", SrcLangExt::Lex,
".l" },
5120 [&langName](
const auto &info) { return info.langName==langName; });
5127 if (extName.
at(0)!=
'.') extName.
prepend(
".");
5137 err(
"Failed to assign extension {} to parser {} for language {}\n",
5138 extName.
data(),it1->parserName,language);
5226 if (extName.
isEmpty()) extName=
".no_extension";
5227 if (extName.
at(0)!=
'.') extName.
prepend(
".");
5243 if (lang == SrcLangExt::Unknown)
5247 if (langName.
at(0)==
'.') langName = langName.
mid(1);
5249 [&langName](
const auto &info) { return info.langName==langName; });
5252 lang = it->parserId;
5253 fileName = it->defExt;
5257 return SrcLangExt::Cpp;
5266 int lastDot = fn.
findRev(
'.');
5267 if (lastDot!=-1)
return fn.
mid(lastDot);
5276 if (scope==
nullptr ||
5296 if (qualifierIndex!=-1)
5298 explicitScopePart = name.
left(qualifierIndex);
5300 name = name.
mid(qualifierIndex+2);
5304 int minDistance = 10000;
5313 if (distance!=-1 && distance<minDistance)
5315 minDistance = distance;
5329 if (bestMatch && bestMatch->
isTypedef())
5337 if (startPos>=len)
return len;
5338 uint8_t c =
static_cast<uint8_t
>(utf8Str[startPos]);
5343 int (*matcher)(int) =
nullptr;
5344 c =
static_cast<uint8_t
>(utf8Str[startPos+bytes]);
5348 c =
static_cast<uint8_t
>(utf8Str[startPos+bytes]);
5352 matcher = std::isxdigit;
5356 matcher = std::isdigit;
5359 else if (std::isalnum(c))
5362 matcher = std::isalnum;
5366 while ((c =
static_cast<uint8_t
>(utf8Str[startPos+bytes]))!=0 && matcher(c))
5376 return startPos+bytes;
5393 .setAutolinkSupport(
false))
5395 auto astImpl =
dynamic_cast<const DocNodeAST*
>(ast.get());
5399 std::visit(visitor,astImpl->root);
5404 int l=
static_cast<int>(result.
length());
5408 if (charCnt>=80)
break;
5415 if (result.
at(i)==
',' ||
5416 result.
at(i)==
'.' ||
5417 result.
at(i)==
'!' ||
5418 result.
at(i)==
'?' ||
5426 if ( i < l) result=result.
left(i)+
"...";
5427 return result.
data();
5446 auto astImpl =
dynamic_cast<const DocNodeAST*
>(ast.get());
5454 std::visit(visitor,astImpl->root);
5471 if (al.
empty())
return;
5488 .setIndexWords(
true));
5498#ifdef TRACINGSUPPORT
5499 void *backtraceFrames[128];
5500 int frameCount = backtrace(backtraceFrames, 128);
5501 const size_t cmdLen = 40960;
5502 static char cmd[cmdLen];
5504 p +=
qsnprintf(p,cmdLen,
"/usr/bin/atos -p %d ", (
int)getpid());
5505 for (
int x = 0; x < frameCount; x++)
5507 p +=
qsnprintf(p,cmdLen,
"%p ", backtraceFrames[x]);
5509 fprintf(stderr,
"========== STACKTRACE START ==============\n");
5513 while (
size_t len = fread(resBuf, 1,
sizeof(resBuf), fp))
5515 fwrite(resBuf, 1, len, stderr);
5519 fprintf(stderr,
"============ STACKTRACE END ==============\n");
5528 if (
qstricmp(inputEncoding,outputEncoding)==0)
return;
5530 if (cd==
reinterpret_cast<void *
>(-1))
5532 term(
"unsupported character conversion: '{}'->'{}': {}\n"
5533 "Check the INPUT_ENCODING setting in the config file!\n",
5534 inputEncoding,outputEncoding,strerror(errno));
5536 size_t iLeft = contents.size();
5537 const char *srcPtr = contents.data();
5538 size_t tmpBufSize = contents.size()*4+1;
5539 size_t oLeft = tmpBufSize;
5541 tmpBuf.resize(tmpBufSize);
5542 char *dstPtr = tmpBuf.data();
5546 newSize = tmpBufSize-oLeft;
5547 tmpBuf.resize(newSize);
5548 std::swap(contents,tmpBuf);
5553 term(
"{}: failed to translate characters from {} to {}: check INPUT_ENCODING\n",
5554 fileName,inputEncoding,outputEncoding);
5566 if (filterName.
isEmpty() || !filter)
5571 err(
"could not open file {}\n",fileName);
5575 auto fileSize = fi.
size();
5576 contents.resize(fileSize);
5577 f.read(contents.data(),fileSize);
5580 err(
"problems while reading file {}\n",fileName);
5586 QCString cmd=filterName+
" \""+fileName+
"\"";
5591 err(
"could not execute filter {}\n",filterName);
5594 const int bufSize=4096;
5597 while ((numRead=
static_cast<int>(fread(buf,1,bufSize,f)))>0)
5600 contents.append(buf,numRead);
5607 if (contents.size()>=2 &&
5608 static_cast<uint8_t
>(contents[0])==0xFF &&
5609 static_cast<uint8_t
>(contents[1])==0xFE
5614 else if (contents.size()>=2 &&
5615 static_cast<uint8_t
>(contents[0])==0xFE &&
5616 static_cast<uint8_t
>(contents[1])==0xFF
5621 else if (contents.size()>=3 &&
5622 static_cast<uint8_t
>(contents[0])==0xEF &&
5623 static_cast<uint8_t
>(contents[1])==0xBB &&
5624 static_cast<uint8_t
>(contents[2])==0xBF
5627 contents.erase(0,3);
5643 std::string t = title.
str();
5644 static const reg::Ex re(R
"(%[a-z_A-Z]+)");
5648 for (; it!=
end ; ++it)
5650 const auto &match = *it;
5651 size_t i = match.position();
5652 size_t l = match.length();
5653 if (i>p) tf+=t.substr(p,i-p);
5654 tf+=match.str().substr(1);
5663template<
class PatternList,
class PatternElem,
typename PatternGet = QCString(*)(const PatternElem &)>
5665 const PatternList &patList,
5672 if (!patList.empty())
5678 for (
const auto &li : patList)
5680 std::string pattern = getter(li).str();
5681 if (!pattern.empty())
5683 size_t i=pattern.find(
'=');
5684 if (i!=std::string::npos) pattern=pattern.substr(0,i);
5686 if (!caseSenseNames)
5717 auto getter = [](std::string s) ->
QCString {
return s; };
5738 if (extLinksInWindow)
5739 return "target=\"_blank\" ";
5741 return "target=\"_parent\" ";
5758 if (!targetFileName.
isEmpty())
5763 if (!anchor.
isEmpty() && isLocalFile)
5791 result = it->second;
5792 size_t l = result.
length();
5793 if (!relPath.
isEmpty() && l>0 && result.
at(0)==
'.')
5798 if (l>0 && result.
at(l-1)!=
'/') result+=
'/';
5799 if (!href) result.
append(
"\" ");
5818 std::string s=str.
str();
5819 static const reg::Ex re(R
"(##[0-9A-Fa-f][0-9A-Fa-f])");
5825 size_t sl=s.length();
5827 for (; it!=
end ; ++it)
5829 const auto &match = *it;
5830 size_t i = match.position();
5831 size_t l = match.length();
5832 if (i>p) result+=s.substr(p,i-p);
5833 std::string lumStr = match.str().substr(2);
5834#define HEXTONUM(x) (((x)>='0' && (x)<='9') ? ((x)-'0') : \
5835 ((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \
5836 ((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0)
5838 double r = 0,g = 0,b = 0;
5841 pow(level/255.0,gamma/100.0),&r,&g,&b);
5842 int red =
static_cast<int>(r*255.0);
5843 int green =
static_cast<int>(g*255.0);
5844 int blue =
static_cast<int>(b*255.0);
5847 colStr[1]=
hex[red>>4];
5848 colStr[2]=
hex[red&0xf];
5849 colStr[3]=
hex[green>>4];
5850 colStr[4]=
hex[green&0xf];
5851 colStr[5]=
hex[blue>>4];
5852 colStr[6]=
hex[blue&0xf];
5858 if (p<sl) result+=s.substr(p);
5869 err(
"could not copy file {} to {}\n",src,dest);
5883 int m1 = text.
find(marker);
5884 if (m1==-1)
return result;
5889 while (!found && (i=text.
find(
'\n',p))!=-1)
5891 found = (p<=m1 && m1<i);
5907 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp || lang==SrcLangExt::VHDL || lang==SrcLangExt::Python)
5911 else if (lang==SrcLangExt::PHP && !classScope)
5923 static const std::unordered_set<std::string> schemes = {
5924 "http",
"https",
"ftp",
"ftps",
"sftp",
"file",
"news",
"irc",
"ircs"
5927 int colonPos = loc_url.
find(
':');
5928 return colonPos!=-1 && schemes.find(loc_url.
left(colonPos).
str())!=schemes.end();
5950 return (prot!=Protection::Private && prot!=Protection::Package) ||
5951 (prot==Protection::Private && extractPrivate) ||
5952 (prot==Protection::Package && extractPackage);
5963 const char *p=s.
data();
5966 int minIndent=1000000;
5967 bool searchIndent=
true;
5969 bool skipFirst = skipFirstLine;
5972 if (c==
'\t') { indent+=tabSize - (indent%tabSize); }
5973 else if (c==
'\n') { indent=0; searchIndent=
true; skipFirst=
false; }
5974 else if (c==
' ') { indent++; }
5975 else if (searchIndent && !skipFirst)
5978 if (indent<minIndent) minIndent=indent;
5983 if (minIndent==0)
return substitute(s,
"@ilinebr",
"\\ilinebr");
5989 skipFirst=skipFirstLine;
5998 else if (indent<minIndent && !skipFirst)
6002 int newIndent = indent+tabSize-(indent%tabSize);
6016 else if (c==
'\\' &&
literal_at(p,
"ilinebr "))
6019 result <<
"\\ilinebr ";
6022 for (
int j=0;j<minIndent;j++)
if (*(p+j)==
' ') skipAmount++;
6023 if (skipAmount==minIndent)
6030 result <<
"\\ilinebr";
6041 return result.
str();
6049 if (indentationLevel <= 0 || doc.
isEmpty())
return;
6054 const char *src = doc.
data();
6056 bool insideIndent = !skipFirstLine;
6058 if (!skipFirstLine) cnt = indentationLevel;
6066 insideIndent =
true;
6067 cnt = indentationLevel;
6078 insideIndent =
false;
6088 insideIndent =
false;
6093 doc.
resize(
static_cast<uint32_t
>(dst-doc.
data()));
6102 return ( ((allExternals && fd->
isLinkable()) ||
6120uint32_t getUtf8Code(
const QCString& s,
int idx )
6122 const int length = s.
length();
6123 if (idx >= length) {
return 0; }
6124 const uint32_t c0 = (uint8_t)s.
at(idx);
6125 if ( c0 < 0xC2 || c0 >= 0xF8 )
6129 if (idx+1 >= length) {
return 0; }
6130 const uint32_t c1 = ((uint8_t)s.
at(idx+1)) & 0x3f;
6133 return ((c0 & 0x1f) << 6) | c1;
6135 if (idx+2 >= length) {
return 0; }
6136 const uint32_t c2 = ((uint8_t)s.
at(idx+2)) & 0x3f;
6139 return ((c0 & 0x0f) << 12) | (c1 << 6) | c2;
6141 if (idx+3 >= length) {
return 0; }
6143 const uint32_t c3 = ((uint8_t)s.
at(idx+3)) & 0x3f;
6144 return ((c0 & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3;
6156uint32_t getUtf8CodeToLower(
const QCString& s,
int idx )
6158 const uint32_t v = getUtf8Code( s, idx );
6159 return v < 0x7f ? tolower( v ) : v;
6171uint32_t getUtf8CodeToUpper(
const QCString& s,
int idx )
6173 const uint32_t v = getUtf8Code( s, idx );
6174 return v < 0x7f ? toupper( v ) : v;
6188 std::string s = docs.
str();
6189 static const reg::Ex re(R
"(\[([ inout,]+)\])");
6194 const auto &match = *it;
6195 size_t p = match.position();
6196 size_t l = match.length();
6200 std::string dir = match[1].str();
6202 dir.erase(std::remove_if(dir.begin(),dir.end(),
6203 [](
const char c) { return c==
' ' || c==
','; }
6205 unsigned char ioMask=0;
6206 size_t inIndex = dir.find(
"in");
6207 if ( inIndex!=std::string::npos) { dir.erase( inIndex,2); ioMask|=(1<<0); }
6208 size_t outIndex = dir.find(
"out");
6209 if (outIndex!=std::string::npos) { dir.erase(outIndex,3); ioMask|=(1<<1); }
6210 if (dir.empty() && ioMask!=0)
6213 if (ioMask==((1<<0)|(1<<1)))
return "[in,out]";
6214 else if (ioMask==(1<<0))
return "[in]";
6215 else if (ioMask==(1<<1))
return "[out]";
6247 *outListType1=inListType;
6250 if (inProt==Protection::Public)
6257 else if (inProt==Protection::Protected)
6265 *outListType2=inListType.
toPublic();
6268 else if (inProt==Protection::Private)
6278 *outListType1=inListType.
toPublic();
6300 int i= imgExt.
find(
':');
6301 return i==-1 ? imgExt : imgExt.
left(i);
6306 assert(!f.is_open());
6307 bool fileOpened=
FALSE;
6308 bool writeToStdout=outFile==
"-";
6311 f.basic_ios<char>::rdbuf(std::cout.rdbuf());
6326 fileOpened = f.is_open();
6333 static const std::unordered_set<std::string> fortran_C_keywords = {
6334 "character",
"call",
"close",
"common",
"continue",
6335 "case",
"contains",
"cycle",
"class",
"codimension",
6336 "concurrent",
"contiguous",
"critical"
6339 if (*contents !=
'c' && *contents !=
'C')
return false;
6341 const char *c = contents;
6343 while (*c && *c !=
' ') {keyword += *c; c++;}
6344 keyword = keyword.
lower();
6346 return (fortran_C_keywords.find(keyword.
str()) != fortran_C_keywords.end());
6354 bool skipLine=
FALSE;
6360 size_t sizCont = contents.
length();
6361 for (
size_t i=0;i<sizCont;i++)
6365 switch(contents.
at(i))
6372 column += tabSize-1;
6389 if (column==1)
return TRUE;
6390 if (skipLine)
break;
6393 if (column!=6) skipLine=
TRUE;
6396 if (skipLine)
break;
6397 if (column>=7)
return TRUE;
6422 auto skipBlock = [&markerInfo](
const char *p,
const SelectionBlock &blk)
6429 size_t len = markerInfo.
endLen;
6430 bool negate = *(p+markerInfo.
endLen)==
'!';
6432 size_t blkNameLen =
qstrlen(blk.name);
6433 if (
qstrncmp(p+len,blk.name,blkNameLen)==0 &&
6437 return p+len+blkNameLen+markerInfo.
closeLen;
6454 const char *p = s.
data();
6464 bool negate = *(p+len)==
'!';
6466 for (
const auto &blk : blockList)
6468 size_t blkNameLen =
qstrlen(blk.name);
6469 if (
qstrncmp(p+len,blk.name,blkNameLen)==0 &&
6472 bool blockEnabled = blk.enabled!=negate;
6474 p+=len+blkNameLen+markerInfo.
closeLen;
6493 size_t len = markerInfo.
endLen;
6494 bool negate = *(p+len)==
'!';
6496 for (
const auto &blk : blockList)
6498 size_t blkNameLen =
qstrlen(blk.name);
6499 if (
qstrncmp(p+len,blk.name,blkNameLen)==0 &&
6503 p+=len+blkNameLen+markerInfo.
closeLen;
6534 const char *p = s.
data();
6543 bool negate = *(p+len)==
'!';
6549 if (markerInfo.
closeLen==0 && *p==
'\n')
6551 warn(fileName,-1,
"Remaining begin replacement with marker '{}'",marker);
6557 warn(fileName,-1,
"Remaining begin replacement with marker '{}'",marker);
6566 size_t len = markerInfo.
endLen;
6567 bool negate = *(p+len)==
'!';
6573 if (markerInfo.
closeLen==0 && *p==
'\n')
6575 warn(fileName,-1,
"Remaining end replacement with marker '{}'",marker);
6581 warn(fileName,-1,
"Remaining end replacement with marker '{}'",marker);
6598 const char *p=s.
data();
6607 while (*e==
' ' || *e==
'\t') e++;
6629 size_t prev = 0, pos = 0, len = s.length();
6632 pos = s.find(delimiter, prev);
6633 if (pos == std::string::npos) pos = len;
6634 if (pos>prev) result.push_back(s.substr(prev,pos-prev));
6635 prev = pos + delimiter.length();
6637 while (pos<len && prev<len);
6649 for ( ; iter !=
end; ++iter)
6651 const auto &match = *iter;
6652 size_t i=match.position();
6653 size_t l=match.length();
6654 if (i>p) result.push_back(s.substr(p,i-p));
6657 if (p<s.length()) result.push_back(s.substr(p));
6664 auto it = std::find(sv.begin(),sv.end(),s);
6665 return it!=sv.end() ?
static_cast<int>(it-sv.begin()) : -1;
6673 return reg::search(s,match,re) ?
static_cast<int>(match.position()) : -1;
6681 for (
const auto &s : sv)
6683 if (!first) result+=delimiter;
6697 while (residual > 0)
6699 modVal[0] = (upper ?
'A':
'a') + (residual-1)%26;
6700 result = modVal + result;
6701 residual = (residual-1) / 26;
6708 static const char *str_romans_upper[] = {
"M",
"CM",
"D",
"CD",
"C",
"XC",
"L",
"XL",
"X",
"IX",
"V",
"IV",
"I" };
6709 static const char *str_romans_lower[] = {
"m",
"cm",
"d",
"cd",
"c",
"xc",
"l",
"xl",
"x",
"ix",
"v",
"iv",
"i" };
6710 static const int values[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
6711 static const char **str_romans = upper ? str_romans_upper : str_romans_lower;
6716 for (
int i = 0; i < 13; ++i)
6718 while (residual - values[i] >= 0)
6720 result += str_romans[i];
6721 residual -= values[i];
6731 size_t size = s.
length();
6734 const char *data = s.
data();
6737 constexpr auto doxy_nbsp =
"&_doxy_nbsp;";
6738 const int maxIndent=1000000;
6739 int minIndent=maxIndent;
6748 int stop = tabSize - (col%tabSize);
6751 while (stop--) result+=
' ';
6755 if (data[i] ==
'\\')
6761 else if (i+5<size &&
literal_at(data+i,
"iskip"))
6766 else if (i+8<size &&
literal_at(data+i,
"endiskip"))
6798 for (
int j=0;j<bytes-1 && c;j++)
6810 if (!skip && col<minIndent) minIndent=col;
6814 if (minIndent!=maxIndent) refIndent=minIndent;
else refIndent=0;
6823 uint8_t md5_sig[16];
6825 MD5Buffer(projectCookie.
data(),
static_cast<unsigned int>(projectCookie.
length()),md5_sig);
6826 MD5SigToString(md5_sig,sigStr);
6827 sigStr[32]=
'_'; sigStr[33]=0;
6834 int l =
static_cast<int>(name.
length());
6835 int lastSepPos = -1;
6836 const char *p = name.
data();
6845 if (sharpCount==0 && p[i+1]==
':' && p[i+2]==
':')
6859 if (ts==-1) ts=0;
else p+=++ts;
6860 for (i=ts;i<l-1;i++)
6863 if (c==
':' && *p==
':') lastSepPos=i;
6898 case '\t': col+=tabSize - (col%tabSize);
6907 for (
int i=0;i<numBytes-1 && (c=*s++);i++) {}
6908 if (c==0)
return col;
6923 int idx = name.
find(
'<');
6936 int idx = result.
find(
'-');
6937 result = result.
left(idx)+templArgs;
6945 int i = text.
find(
'"');
6969 uint8_t md5_sig[16];
6971 MD5Buffer(content.
data(),
static_cast<unsigned int>(content.
length()),md5_sig);
6972 MD5SigToString(md5_sig,sigStr);
6974 QCString fileName = baseName + sigStr + extension;
6984 file.write( content.
data(), content.
length() );
6989 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
QCString 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 QCString 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
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 QCString docFile() const =0
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 QCString anchor() const =0
virtual bool isLinkableInProject() const =0
virtual const Definition * findInnerCompound(const QCString &name) const =0
virtual QCString getReference() const =0
virtual const GroupList & partOfGroups() const =0
virtual QCString qualifiedName() const =0
virtual QCString displayName(bool includeScope=TRUE) const =0
virtual bool isArtificial() const =0
virtual QCString getOutputFileBase() const =0
virtual Definition * getOuterScope() const =0
virtual int getStartBodyLine() const =0
virtual bool isReference() const =0
virtual const QCString & name() const =0
virtual void setBodySegment(int defLine, int bls, int ble)=0
virtual void setDocumentation(const QCString &d, const QCString &docFile, int docLine, bool stripWhiteSpace=TRUE)=0
virtual void setLanguage(SrcLangExt lang)=0
virtual void setReference(const QCString &r)=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 isEmpty(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
static std::string cleanDirPath(const std::string &path)
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 QCString htmlFileExtension
static PageLinkedMap * pageLinkedMap
static DirLinkedMap * dirLinkedMap
static MemberNameLinkedMap * memberNameLinkedMap
static SymbolMap< Definition > * symbolMap
static FileNameLinkedMap * exampleNameLinkedMap
static GroupLinkedMap * groupLinkedMap
Wrapper class for the Entry type.
A model of a file symbol.
virtual ModuleDef * getModuleDef() const =0
virtual QCString getPath() const =0
virtual bool generateSourceFile() const =0
virtual QCString absFilePath() const =0
virtual bool isDocumentationFile() const =0
Minimal replacement for QFileInfo.
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
Class representing all files with a certain base name.
Ordered dictionary of FileName objects.
A model of a group of symbols.
virtual void addPage(PageDef *def)=0
Generator for HTML code fragments.
Concrete visitor implementation for HTML output.
static HtmlEntityMapper & instance()
Returns the one and only instance of the HTML entity mapper.
SymType name2sym(const QCString &symName) const
Give code of the requested HTML entity name.
const T * find(const std::string &key) const
A model of a class/file/namespace member symbol.
virtual QCString typeString() 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 bool isVariable() const =0
virtual QCString argsString() 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 endPageRef(const QCString &c, const QCString &a)
void writeString(const QCString &text)
void disable(OutputType o)
void writeObjectLink(const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name)
void startConstraintParam()
void docify(const QCString &s)
void generateDoc(const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &docStr, const DocOptions &options)
void startConstraintDocs()
void startConstraintType()
void pushGeneratorState()
void disableAllBut(OutputType o)
void endConstraintParam()
void startConstraintList(const QCString &header)
void parseText(const QCString &textStr)
A model of a page symbol.
virtual void setTitle(const QCString &title)=0
virtual void setNestingLevel(int)=0
virtual bool hasTitle() const =0
virtual void setFileName(const QCString &name)=0
virtual void setShowLineNo(bool)=0
virtual QCString title() const =0
virtual void setPageScope(Definition *)=0
virtual const GroupDef * getGroupDef() const =0
This is an alternative implementation of QCString.
int find(char c, int index=0, bool cs=TRUE) const
QCString & prepend(const char *s)
size_t length() const
Returns the length of the string, not counting the 0-terminator.
bool startsWith(const char *s) const
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
bool endsWith(const char *s) const
char & at(size_t i)
Returns a reference to the character at index i.
char * rawData()
Returns a writable pointer to the data.
bool isEmpty() const
Returns TRUE iff the string is empty.
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
void resize(size_t newlen)
const std::string & str() const
QCString & setNum(short n)
QCString simplifyWhiteSpace() const
return a copy of this string with leading and trailing whitespace removed and multiple whitespace cha...
QCString & append(char c)
QCString right(size_t len) const
void reserve(size_t size)
Reserve space for size bytes without changing the string contents.
QCString & sprintf(const char *format,...)
int findRev(char c, int index=-1, bool cs=TRUE) const
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
std::string_view view() const
QCString left(size_t len) const
int contains(char c, bool cs=TRUE) const
bool stripPrefix(const QCString &prefix)
This struct represents an item in the list of references.
class that provide information about a section.
Definition * definition() const
QCString fileName() const
void setTitle(const QCString &t)
SectionInfo * replace(const QCString &label, const QCString &fileName, int lineNr, const QCString &title, SectionType type, int level, const QCString &ref=QCString())
SectionInfo * add(const SectionInfo &si)
static SectionManager & instance()
returns a reference to the singleton
static constexpr int Page
int isAccessibleFrom(const Definition *scope, const Definition *item)
Checks if symbol item is accessible from within scope.
int isAccessibleFromWithExpScope(const Definition *scope, const Definition *item, const QCString &explicitScopePart)
Check if symbol item is accessible from within scope, where it has to match the explicitScopePart.
QCString getResolvedType() const
In case a call to resolveClass() points to a typedef or using declaration.
const Definition * resolveSymbol(const Definition *scope, const QCString &name, const QCString &args=QCString(), bool checkCV=false, bool insideCode=false, bool onlyLinkable=false)
Find the symbool definition matching name within the scope set.
const ClassDef * resolveClass(const Definition *scope, const QCString &name, bool maybeUnlinkable=false, bool mayBeHidden=false)
Find the class definition matching name within the scope set.
QCString 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.
Concrete visitor implementation for TEXT output.
Abstract interface for a hyperlinked text fragment.
virtual void writeString(std::string_view, bool) const =0
virtual void writeBreak(int indent) const =0
virtual void writeLink(const QCString &extRef, const QCString &file, const QCString &anchor, std::string_view text) const =0
Implements TextGeneratorIntf for an OutputDocInterface stream.
TextGeneratorOLImpl(OutputList &ol)
void writeBreak(int indent) const override
void writeLink(const QCString &extRef, const QCString &file, const QCString &anchor, std::string_view text) const override
void writeString(std::string_view s, bool keepSpaces) const override
Text streaming class that buffers data.
std::string str() const
Return the contents of the buffer as a std::string object.
ClassDef * getClass(const QCString &n)
ClassDef * toClassDef(Definition *d)
std::vector< BaseClassDef > BaseClassList
Class representing a regular expression.
@ Wildcard
simple globbing pattern.
Class to iterate through matches.
Object representing the matching results.
ConceptDef * toConceptDef(Definition *d)
ConceptDef * getConcept(const QCString &n)
#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
QCString formatDateTime(const QCString &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...
QCString dateTimeFromString(const QCString &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 QCString &argsString, QCString *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 validatingParseDoc(IDocParser &parserIntf, const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &input, const DocOptions &options)
IDocParserPtr createDocParser()
factory function to create a parser
IDocNodeASTPtr validatingParseTitle(IDocParser &parserIntf, const QCString &fileName, int lineNr, const QCString &input)
static void addMembersToMemberGroup()
FileDef * toFileDef(Definition *d)
Translator * theTranslator
MemberDefMutable * toMemberDefMutable(Definition *d)
MemberDef * toMemberDef(Definition *d)
#define warn(file, line, fmt,...)
ModuleDef * toModuleDef(Definition *d)
std::ifstream openInputStream(const QCString &name, bool binary=false, bool openAtEnd=false)
FILE * popen(const QCString &name, const QCString &type)
std::ofstream openOutputStream(const QCString &name, bool append=false)
bool fileSystemIsCaseSensitive()
void replaceNamespaceAliases(QCString &name)
NamespaceDef * getResolvedNamespace(const QCString &name)
NamespaceDef * toNamespaceDef(Definition *d)
bool search(std::string_view str, Match &match, const Ex &re, size_t pos)
Search in a given string str starting at position pos for a match against regular expression re.
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 QCString &f, int l, const QCString &n, const QCString &d, const QCString &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)
int qstricmp(const char *s1, const char *s2)
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
int qstrncmp(const char *str1, const char *str2, size_t len)
const char * qPrint(const char *s)
uint32_t qstrlen(const char *str)
Returns the length of string str, or 0 if a null pointer is passed.
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.
Cache element for the file name to FileDef mapping cache.
FindFileCacheElem(FileDef *fd, bool ambig)
const ArgumentList * argumentList() const
const Definition * scope() const
const Definition * self() const
size_t breakThreshold() const
const FileDef * fileScope() const
This struct is used to capture the tag file information for an Entry.
static constexpr const char * to_string(Protection prot) noexcept
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.
QCString writeFileContents(const QCString &baseName, const QCString &extension, const QCString &content, bool &exists)
Thread-safe function to write a string to a file.
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
bool matchArguments2(const Definition *srcScope, const FileDef *srcFileScope, const QCString &srcReturnType, const ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, const QCString &dstReturnType, const ArgumentList *dstAl, bool checkCV, SrcLangExt lang)
QCString removeRedundantWhiteSpace(const QCString &s)
QCString extractDirection(QCString &docs)
Strip the direction part from docs and return it as a string in canonical form The input docs string ...
QCString mergeScopes(const QCString &leftScope, const QCString &rightScope)
QCString findFilePath(const QCString &file, bool &ambig)
QCString normalizeNonTemplateArgumentsInString(const QCString &name, const Definition *context, const ArgumentList &formalArgs)
QCString linkToText(SrcLangExt lang, const QCString &link, bool isFileName)
QCString convertToJSString(const QCString &s, bool keepEntities, bool singleQuotes)
size_t updateColumnCount(const char *s, size_t col)
static std::mutex writeFileContents_lock
void trimBaseClassScope(const BaseClassList &bcl, QCString &s, int level=0)
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
QCString insertTemplateSpecifierInScope(const QCString &scope, const QCString &templ)
bool protectionLevelVisible(Protection prot)
QCString generateAnonymousAnchor(const QCString &fileName, int count)
static std::unordered_map< std::string, QCString > g_docCache
QCString parseCommentAsHtml(const Definition *scope, const MemberDef *member, const QCString &doc, const QCString &fileName, int lineNr)
std::string join(const StringVector &sv, const std::string &delimiter)
create a string where the string in the vector are joined by the given delimiter
bool matchTemplateArguments(const ArgumentList &srcAl, const ArgumentList &dstAl)
int lineBlock(const QCString &text, const QCString &marker)
Returns the line number of the line following the line with the marker.
void addCodeOnlyMappings()
QCString convertToHtml(const QCString &s, bool keepEntities)
QCString substituteTemplateArgumentsInString(const QCString &nm, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
static int g_usedNamesCount
static void filterCRLF(std::string &contents)
bool resolveRef(const QCString &scName, const QCString &name, bool inSeeBlock, const Definition **resContext, const MemberDef **resMember, SrcLangExt lang, bool lookForSpecialization, const FileDef *currentFile, bool checkScope)
QCString stripIndentation(const QCString &s, bool skipFirstLine)
QCString parseCommentAsText(const Definition *scope, const MemberDef *md, const QCString &doc, const QCString &fileName, int lineNr)
int extractClassNameFromType(const QCString &type, int &pos, QCString &name, QCString &templSpec, SrcLangExt lang)
QCString integerToRoman(int n, bool upper)
void checkBlocks(const QCString &s, const QCString fileName, const SelectionMarkerInfo &markerInfo)
void stripIndentationVerbatim(QCString &doc, const int indentationLevel, bool skipFirstLine)
void writeTypeConstraints(OutputList &ol, const Definition *d, const ArgumentList &al)
bool leftScopeMatch(const QCString &scope, const QCString &name)
QCString correctURL(const QCString &url, const QCString &relPath)
Corrects URL url according to the relative path relPath.
QCString stripAnonymousNamespaceScope(const QCString &s)
QCString stripPath(const QCString &s)
QCString stripFromIncludePath(const QCString &path)
static Cache< std::string, FindFileCacheElem > g_findFileDefCache(5000)
QCString removeEmptyLines(const QCString &s)
QCString extractEndRawStringDelimiter(const char *rawEnd)
static const char constScope[]
static bool recursivelyAddGroupListToTitle(OutputList &ol, const Definition *d, bool root)
bool containsWord(const QCString &str, const char *word)
returns TRUE iff string s contains word w
bool checkIfTypedef(const Definition *scope, const FileDef *fileScope, const QCString &n)
bool readInputFile(const QCString &fileName, std::string &contents, bool filter, bool isSourceCode)
read a file name fileName and optionally filter and transcode it
bool transcodeCharacterStringToUTF8(std::string &input, const char *inputEncoding)
static bool matchCanonicalTypes(const Definition *srcScope, const FileDef *srcFileScope, const QCString &srcType, const Definition *dstScope, const FileDef *dstFileScope, const QCString &dstType, SrcLangExt lang)
bool patternMatch(const FileInfo &fi, const StringVector &patList)
void generateFileRef(OutputList &ol, const QCString &name, const QCString &text)
QCString generateMarker(int id)
QCString selectBlocks(const QCString &s, const SelectionBlockList &blockList, const SelectionMarkerInfo &markerInfo)
remove disabled blocks and all block markers from s and return the result as a string
static std::mutex g_findFileDefMutex
QCString escapeCharsInString(const QCString &name, bool allowDots, bool allowUnderscore)
static std::unordered_map< std::string, SrcLangExt > g_extLookup
static QCString stripDeclKeywords(const QCString &s)
bool recognizeFixedForm(const QCString &contents, FortranFormat format)
bool openOutputFile(const QCString &outFile, std::ofstream &f)
QCString substituteKeywords(const QCString &file, const QCString &s, const KeywordSubstitutionList &keywords)
static MemberDef * getMemberFromSymbol(const Definition *scope, const FileDef *fileScope, const QCString &n)
QCString tempArgListToString(const ArgumentList &al, SrcLangExt lang, bool includeDefault)
static ModuleDef * findModuleDef(const Definition *d)
void addRefItem(const RefItemVector &sli, const QCString &key, const QCString &prefix, const QCString &name, const QCString &title, const QCString &args, const Definition *scope)
void addGroupListToTitle(OutputList &ol, const Definition *d)
QCString relativePathToRoot(const QCString &name)
SrcLangExt getLanguageFromCodeLang(QCString &fileName)
Routine to handle the language attribute of the \code command.
QCString integerToAlpha(int n, bool upper)
void writePageRef(OutputList &ol, const QCString &cn, const QCString &mn)
void clearSubDirs(const Dir &d)
static void transcodeCharacterBuffer(const QCString &fileName, std::string &contents, const QCString &inputEncoding, const QCString &outputEncoding)
QCString showFileDefMatches(const FileNameLinkedMap *fnMap, const QCString &n)
QCString demangleCSharpGenericName(const QCString &name, const QCString &templArgs)
QCString fileToString(const QCString &name, bool filter, bool isSourceCode)
QCString stripExtensionGeneral(const QCString &fName, const QCString &ext)
QCString filterTitle(const QCString &title)
QCString unescapeCharsInString(const QCString &s)
QCString removeAnonymousScopes(const QCString &str)
void createSubDirs(const Dir &d)
bool fileVisibleInIndex(const FileDef *fd, bool &genSourceFile)
QCString stripScope(const QCString &name)
QCString resolveTypeDef(const Definition *context, const QCString &qualifiedName, const Definition **typedefContext)
bool checkExtension(const QCString &fName, const QCString &ext)
bool isURL(const QCString &url)
Checks whether the given url starts with a supported protocol.
QCString inlineTemplateArgListToDoc(const ArgumentList &al)
bool resolveLink(const QCString &scName, const QCString &lr, bool, const Definition **resContext, QCString &resAnchor, SrcLangExt lang, const QCString &prefix)
int computeQualifiedIndex(const QCString &name)
Return the index of the last :: in the string name that is still before the first <.
QCString stripExtension(const QCString &fName)
void initDefaultExtensionMapping()
bool findAndRemoveWord(QCString &sentence, const char *word)
removes occurrences of whole word from sentence, while keeps internal spaces and reducing multiple se...
static QCString stripFromPath(const QCString &p, const StringVector &l)
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
static bool isLowerCase(QCString &s)
static const char virtualScope[]
QCString convertToXML(const QCString &s, bool keepEntities)
QCString langToString(SrcLangExt lang)
Returns a string representation of lang.
QCString determineAbsoluteIncludeName(const QCString &curFile, const QCString &incFileName)
QCString detab(const QCString &s, size_t &refIndent)
EntryType guessSection(const QCString &name)
void extractNamespaceName(const QCString &scopeName, QCString &className, QCString &namespaceName, bool allowEmptyClass)
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[]
QCString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
int findIndex(const StringVector &sv, const std::string &s)
find the index of a string in a vector of strings, returns -1 if the string could not be found
static void stripIrrelevantString(QCString &target, const QCString &str, bool insideTemplate)
QCString removeLongPathMarker(QCString path)
QCString correctId(const QCString &s)
static QCString extractCanonicalArgType(const Definition *d, const FileDef *fs, const Argument &arg, SrcLangExt lang)
QCString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Returns the scope separator to use given the programming language lang.
void mergeMemberOverrideOptions(MemberDefMutable *md1, MemberDefMutable *md2)
static int nextUTF8CharPosition(const QCString &utf8Str, uint32_t len, uint32_t startPos)
QCString getDotImageExtension()
static QCString extractCanonicalType(const Definition *d, const FileDef *fs, QCString type, SrcLangExt lang, bool insideTemplate)
static QCString getCanonicalTypeForIdentifier(const Definition *d, const FileDef *fs, const QCString &word, SrcLangExt lang, QCString *tSpec, int count=0)
QCString mangleCSharpGenericName(const QCString &name)
GetDefResult getDefs(const GetDefInput &input)
QCString makeBaseName(const QCString &name, const QCString &ext)
QCString projectLogoFile()
static std::mutex g_usedNamesMutex
PageDef * addRelatedPage(const QCString &name, const QCString &ptitle, const QCString &doc, const QCString &fileName, int docLine, int startLine, const RefItemVector &sli, GroupDef *gd, const TagInfo *tagInfo, bool xref, SrcLangExt lang)
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)
StringVector split(const std::string &s, const std::string &delimiter)
split input string s by string delimiter delimiter.
QCString getEncoding(const FileInfo &fi)
static std::mutex g_docCacheMutex
void linkifyText(const TextGeneratorIntf &out, const QCString &text, const LinkifyTextOptions &options)
static bool keyWordsFortranC(const char *contents)
FortranFormat convertFileNameFortranParserCode(QCString fn)
static QCString getCanonicalTemplateSpec(const Definition *d, const FileDef *fs, const QCString &spec, SrcLangExt lang)
bool genericPatternMatch(const FileInfo &fi, const PatternList &patList, PatternElem &elem, PatternGet getter)
QCString stripLeadingAndTrailingEmptyLines(const QCString &s, int &docLine)
Special version of QCString::stripWhiteSpace() that only strips completely blank lines.
int findParameterList(const QCString &name)
Returns the position in the string where a function parameter list begins, or -1 if one is not found.
bool copyFile(const QCString &src, const QCString &dest)
Copies the contents of file with name src to the newly created file with name dest.
QCString externalLinkTarget(const bool parent)
QCString getFileFilter(const QCString &name, bool isSourceCode)
void stripIrrelevantConstVolatile(QCString &s, bool insideTemplate)
QCString extractBeginRawStringDelimiter(const char *rawStart)
QCString stripTemplateSpecifiersFromScope(const QCString &fullName, bool parentOnly, QCString *pLastScopeStripped, QCString scopeName, bool allowArtificial)
QCString getOverloadDocs()
static QCString getFilterFromList(const QCString &name, const StringVector &filterList, bool &found)
static QCString projectLogoSize()
void cleanupInlineGraph()
static QCString showDate(const QCString &fmt)
int getPrefixIndex(const QCString &name)
bool rightScopeMatch(const QCString &scope, const QCString &name)
void writeMarkerList(OutputList &ol, const std::string &markerText, size_t numMarkers, std::function< void(size_t)> replaceFunc)
static bool getScopeDefs(const QCString &docScope, const QCString &scope, ClassDef *&cd, ConceptDef *&cnd, NamespaceDef *&nd, ModuleDef *&modd)
bool updateLanguageMapping(const QCString &extension, const QCString &language)
QCString inlineArgListToDoc(const ArgumentList &al)
static std::unordered_map< std::string, int > g_usedNames
static CharAroundSpace g_charAroundSpace
QCString replaceColorMarkers(const QCString &str)
Replaces any markers of the form ##AA in input string str by new markers of the form #AABBCC,...
QCString getFileNameExtension(const QCString &fn)
QCString convertToId(const QCString &s)
void writeExamples(OutputList &ol, const ExampleList &list)
static std::mutex g_matchArgsMutex
QCString replaceAnonymousScopes(const QCString &s, const QCString &replacement)
static const char operatorScope[]
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
QCString convertCharEntitiesToUTF8(const QCString &str)
static std::vector< Lang2ExtMap > g_lang2extMap
int getScopeFragment(const QCString &s, int p, int *l)
void addHtmlExtensionIfMissing(QCString &fName)
QCString createHtmlUrl(const QCString &relPath, const QCString &ref, bool href, bool isLocalFile, const QCString &targetFileName, const QCString &anchor)
A bunch of utility functions.
std::vector< KeywordSubstitution > KeywordSubstitutionList
std::vector< SelectionBlock > SelectionBlockList