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;
137 const QCString &anchor,std::string_view 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;
1842 if (i-pp>=2 && type[i-2]==
':' && type[i-1]==
':')
1844 canType += type.
mid(pp,i-pp-2);
1848 canType += type.
mid(pp,i-pp);
1871 std::string ts = templSpec.
str();
1872 static const reg::Ex re(R
"(\a\w*)");
1879 for (; it!=
end ; ++it)
1881 const auto &match = *it;
1882 size_t ti = match.position();
1883 size_t tl = match.length();
1884 std::string matchStr = match.str();
1885 canType += ts.substr(tp,ti-tp);
1889 canType+=ts.substr(tp);
1905 if ((type==
"const" || type==
"volatile") && !name.
isEmpty())
1910 if (name==
"const" || name==
"volatile")
1912 if (!type.
isEmpty()) type+=
" ";
1930#define MATCH AUTO_TRACE_EXIT("match at line {}",__LINE__);
1931#define NOMATCH AUTO_TRACE_EXIT("no match at line {}",__LINE__);
1938 AUTO_TRACE(
"srcType='{}' dstType='{}'",srcType,dstType);
1939 if (srcType==dstType)
return true;
1942 int i1=srcType.
find(
")(");
1943 if (i1==-1)
return false;
1944 int i2=dstType.
find(
")(");
1945 if (i1!=i2)
return false;
1948 int j1=srcType.
find(
"(");
1949 if (j1==-1 || j1>i1)
return false;
1950 int j2=dstType.
find(
"(");
1951 if (j2!=j1)
return false;
1952 if (srcType.
left(j1)!=dstType.
left(j2))
return false;
1961 dstScope,dstFileScope,dstType.
left(j2),dstAl.get(),
1971 AUTO_TRACE(
"src: scope={} type={} name={} canType={}, dst: scope={} type={} name={} canType={}",
1990 srcA.
type+=sSrcName;
1994 else if (sDstName==srcType.
right(sDstName.
length()))
1996 dstA.
type+=sDstName;
2012 dstScope,dstFileScope,dstA.
canType,
2035 ASSERT(srcScope!=
nullptr && dstScope!=
nullptr);
2037 AUTO_TRACE(
"srcScope='{}' dstScope='{}' srcArgs='{}' dstArgs='{}' checkCV={} lang={}",
2040 if (srcAl==
nullptr || dstAl==
nullptr)
2042 bool match = srcAl==dstAl;
2073 if (srcAl->
size() != dstAl->
size())
2107 auto srcIt = srcAl->
begin();
2108 auto dstIt = dstAl->
begin();
2109 for (;srcIt!=srcAl->
end() && dstIt!=dstAl->
end();++srcIt,++dstIt)
2114 dstScope,dstFileScope,dstA,
2133 AUTO_TRACE(
"srcAl='{}',dstAl='{}',forceNameOverwrite={}",
2141 auto srcIt=srcAl.
begin();
2142 auto dstIt=dstAl.
begin();
2143 while (srcIt!=srcAl.
end() && dstIt!=dstAl.
end())
2148 AUTO_TRACE_ADD(
"before merge: src=[type='{}',name='{}',def='{}'] dst=[type='{}',name='{}',def='{}']",
2164 if (srcA.
name==
"const" || srcA.
name==
"volatile")
2169 if (dstA.
name==
"const" || dstA.
name==
"volatile")
2195 if (forceNameOverwrite)
2238 j1=
static_cast<int>(srcA.
type.
length())-i1-2,
2239 j2=
static_cast<int>(dstA.
type.
length())-i2-2;
2247 else if (i1==-1 && i2!=-1 && dstA.
type.
right(j2)==srcA.
type)
2267 AUTO_TRACE_ADD(
"after merge: src=[type='{}',name='{}',def='{}'] dst=[type='{}',name='{}',def='{}']",
2283 auto isUnconstraintTemplate = [](
const QCString &type)
2285 return type==
"typename" || type==
"class" || type.startsWith(
"typename ") || type.startsWith(
"class ");
2287 auto srcIt = srcAl.
begin();
2288 auto dstIt = dstAl.
begin();
2289 while (srcIt!=srcAl.
end() && dstIt!=dstAl.
end())
2293 if ((!isUnconstraintTemplate(srcA.
type) || !isUnconstraintTemplate(dstA.
type)) && srcA.
type!=dstA.
type)
2312 AUTO_TRACE(
"scopeName={},memberName={},forceEmptyScope={}",
2338 result.
found =
true;
2343 result.
found =
true;
2348 result.
found =
true;
2353 result.
found =
true;
2358 result.
found =
true;
2390 bool explicitGlobalScope=
FALSE;
2391 if (scopeName.
at(0)==
':' && scopeName.
at(1)==
':')
2394 explicitGlobalScope=
TRUE;
2402 int scopeOffset=explicitGlobalScope ? 0 :
static_cast<int>(docScopeName.
length());
2407 if (scopeOffset>0) fullName.
prepend(docScopeName.
left(scopeOffset)+
"::");
2431 else if ((scopeOffset=docScopeName.
findRev(
"::",scopeOffset-1))==-1)
2435 }
while (scopeOffset>=0);
2443 const char *p=s.
data();
2445 while ((c=
static_cast<uint8_t
>(*p++)))
if (!islower(c))
return false;
2458 bool lookForSpecialization,
2463 AUTO_TRACE(
"scope={} name={} inSeeBlock={} lang={} lookForSpecialization={} currentFile={} checkScope={}",
2464 scName,name,inSeeBlock,lang,lookForSpecialization,currentFile ? currentFile->
name() :
"", checkScope);
2469 if (fullName.
find(
"anonymous_namespace{")==-1)
2479 if (lang==SrcLangExt::CSharp && (templStartPos=fullName.
find(
'<'))!=-1)
2481 int templEndPos = fullName.
findRev(
'>');
2482 if (templEndPos!=-1)
2490 int endNamePos=bracePos!=-1 ? bracePos :
static_cast<int>(fullName.
length());
2491 int scopePos=fullName.
findRev(
"::",endNamePos);
2492 bool explicitScope = fullName.
startsWith(
"::") &&
2497 bool allowTypeOnly=
false;
2500 *resContext=
nullptr;
2507 if (!inSeeBlock && scopePos==-1 &&
isLowerCase(tsName))
2521 if (scName!=fullName &&
getScopeDefs(scName,fullName,cd,cnd,nd,modd))
2544 else if (scName==fullName || (!inSeeBlock && scopePos==-1))
2563 if (explicitScope) nameStr=nameStr.
mid(2);
2568 if (bracePos!=-1) argsStr=fullName.
right(fullName.
length()-bracePos);
2572 int templPos=nameStr.
find(
'<');
2573 bool tryUnspecializedVersion =
FALSE;
2574 if (templPos!=-1 && nameStr.
find(
"operator")==-1)
2576 int endTemplPos=nameStr.
findRev(
'>');
2577 if (endTemplPos!=-1)
2579 if (!lookForSpecialization)
2581 nameStr=nameStr.
left(templPos)+nameStr.
right(nameStr.
length()-endTemplPos-1);
2585 tryUnspecializedVersion =
TRUE;
2593 nameStr=nameStr.
mid(scopeStr.
length()+2);
2619 *resContext=
nullptr;
2629 *resMember=result.
md;
2630 *resContext=result.
md;
2634 *resContext=
nullptr;
2640 else if (result.
cd) *resContext=result.
cd;
2641 else if (result.
nd) *resContext=result.
nd;
2642 else if (result.
fd) *resContext=result.
fd;
2643 else if (result.
gd) *resContext=result.
gd;
2644 else if (result.
cnd) *resContext=result.
cnd;
2645 else if (result.
modd) *resContext=result.
modd;
2648 *resContext=
nullptr; *resMember=
nullptr;
2675 else if (tsName.
find(
'.')!=-1)
2687 if (tryUnspecializedVersion)
2689 bool b =
resolveRef(scName,name,inSeeBlock,resContext,resMember,lang,
FALSE,
nullptr,checkScope);
2717 if (!ignoreDots && result.
find(
'<')==-1) result=
substitute(result,
".",
"::",3);
2719 if (result.
at(0)==
':' && result.
at(1)==
':')
2759 *resContext=
nullptr;
2762 if (lang==SrcLangExt::CSharp)
2767 AUTO_TRACE(
"scName='{}',ref='{}'",scName,lr);
2772 const DirDef *dir =
nullptr;
2790 if (si) resAnchor = si->
label();
2802 resAnchor = si->
label();
2809 resAnchor = si->
label();
2839 else if (lang==SrcLangExt::Java &&
2840 (cd=
getClass(linkRefWithoutTemplates)))
2847 else if ((cd=
getClass(linkRef+
"-p")))
2864 resAnchor=modd->
anchor();
2884 if (md) resAnchor=md->
anchor();
2922 if (n.
isEmpty())
return nullptr;
2925 const int maxAddrSize = 20;
2926 char addr[maxAddrSize];
2927 qsnprintf(addr,maxAddrSize,
"%p:",
reinterpret_cast<const void*
>(fnMap));
2936 ambig = cachedResult->
isAmbig;
2947 if (name.
isEmpty())
return nullptr;
2954 if (name.
isEmpty())
return nullptr;
2961 const std::unique_ptr<FileDef> &fd = fn->front();
2963 fd->getPath().right(path.
length())==path :
2965 if (path.
isEmpty() || isSamePath)
2967 cachedResult->
fileDef = fd.get();
2976 for (
const auto &fd_p : *fn)
2980 if (fdStripPath == pathStripped)
2997 cachedResult->
isAmbig = ambig;
2998 cachedResult->
fileDef = lastMatch;
3028 for (
const auto &s : examplePathList)
3070 for (
const auto &fd_p : *fn)
3078 if (!first) result +=
"\n";
3092 std::string substRes;
3094 const char *p = s.
data();
3098 substRes.reserve(s.
length()+1024);
3105 for (
const auto &kw : keywords)
3107 size_t keyLen =
qstrlen(kw.keyword);
3108 if (
qstrncmp(p,kw.keyword,keyLen)==0)
3110 const char *startArg = p+keyLen;
3111 bool expectParam = std::holds_alternative<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
3113 if (expectParam && *startArg==
'(')
3116 const char *endArg =
nullptr;
3117 while ((c=*(startArg+j)) && c!=
')' && c!=
'\n' && c!=0) j++;
3118 if (c==
')') endArg=startArg+j;
3122 auto &&getValue = std::get<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
3123 substRes+=getValue(value).str();
3130 warn(file,line,
"Missing argument for '{}'",kw.keyword);
3134 else if (!expectParam)
3136 auto &&getValue = std::get<KeywordSubstitution::GetValue>(kw.getValueVariant);
3137 substRes+=getValue().str();
3144 warn(file,line,
"Expected arguments for '{}' but none were specified",kw.keyword);
3154 if (c==
'\n') line++;
3182 int wi = projectLogo.
find(
" width=");
3185 projectLogo = projectLogo.
left(wi);
3187 int hi = projectLogo.
find(
" height=");
3190 projectLogo = projectLogo.
left(hi);
3203 auto extractDimension = [&projectLogo](
const char *startMarker,
size_t startPos,
size_t endPos) ->
QCString
3206 if (result.
length()>=2 && result.
at(0)!=
'"' && result.
at(result.
length()-1)!=
'"')
3208 result=
"\""+result+
"\"";
3214 int wi = projectLogo.
find(
" width=");
3215 int hi = projectLogo.
find(
" height=");
3216 if (wi!=-1 && hi!=-1)
3220 sizeVal = extractDimension(
" width=", wi+7, hi) +
" "
3221 + extractDimension(
" height=", hi+8, projectLogo.
length());
3225 sizeVal = extractDimension(
" height=", hi+8, wi) +
" "
3226 + extractDimension(
" width=", wi+7, projectLogo.
length());
3231 sizeVal = extractDimension(
" width=", wi+7, projectLogo.
length());
3235 sizeVal = extractDimension(
" height=", hi+8, projectLogo.
length());
3248 {
"$title", [&]() {
return !title.
isEmpty() ? title : projName; } },
3249 {
"$doxygenversion", [&]() {
return getDoxygenVersion(); } },
3250 {
"$projectname", [&]() {
return projName; } },
3251 {
"$projectnumber", [&]() {
return projNum; } },
3252 {
"$projectbrief", [&]() {
return projBrief; } },
3272 for (
const auto &s : sl)
3274 const char *ps=s.c_str();
3275 const char *pd=name.
data();
3277 while (*ps!=0 && *pd!=0 && *ps==*pd)
3283 if (*ps==0 && *pd!=0)
3289 if (result<
static_cast<int>(name.
length())-1 && name.
at(result)==
'[') result++;
3301int getUtf8Char(
const char *input,
char ids[MAX_UTF8_CHAR_SIZE],CaseModifier modifier)
3304 const unsigned char uc = (
unsigned char)*input;
3305 bool validUTF8Char =
false;
3308 const char* pt = input+1;
3310 if ((uc&0x80)==0x00)
3314 case CaseModifier::None: ids[0]=*input;
break;
3315 case CaseModifier::ToUpper: ids[0]=(char)toupper(*input);
break;
3316 case CaseModifier::ToLower: ids[0]=(char)tolower(*input);
break;
3323 if ((uc&0xE0)==0xC0)
3327 if ((uc&0xF0)==0xE0)
3331 if ((uc&0xF8)==0xF0)
3336 validUTF8Char = l>0;
3337 for (
int m=1; m<l && validUTF8Char; ++m)
3339 unsigned char ct = (
unsigned char)*pt;
3340 if (ct==0 || (ct&0xC0)!=0x80)
3342 validUTF8Char=
false;
3363 if (caseSenseNames == CASE_SENSE_NAMES_t::YES)
return true;
3364 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO)
return false;
3370 if (name.
isEmpty())
return name;
3376 const char *p=name.
data();
3381 case '_':
if (allowUnderscore) result+=
'_';
else result+=
"__";
break;
3382 case '-': result+=
'-';
break;
3383 case ':': result+=
"_1";
break;
3384 case '/': result+=
"_2";
break;
3385 case '<': result+=
"_3";
break;
3386 case '>': result+=
"_4";
break;
3387 case '*': result+=
"_5";
break;
3388 case '&': result+=
"_6";
break;
3389 case '|': result+=
"_7";
break;
3390 case '.':
if (allowDots) result+=
'.';
else result+=
"_8";
break;
3391 case '!': result+=
"_9";
break;
3392 case ',': result+=
"_00";
break;
3393 case ' ': result+=
"_01";
break;
3394 case '{': result+=
"_02";
break;
3395 case '}': result+=
"_03";
break;
3396 case '?': result+=
"_04";
break;
3397 case '^': result+=
"_05";
break;
3398 case '%': result+=
"_06";
break;
3399 case '(': result+=
"_07";
break;
3400 case ')': result+=
"_08";
break;
3401 case '+': result+=
"_09";
break;
3402 case '=': result+=
"_0a";
break;
3403 case '$': result+=
"_0b";
break;
3404 case '\\': result+=
"_0c";
break;
3405 case '@': result+=
"_0d";
break;
3406 case ']': result+=
"_0e";
break;
3407 case '[': result+=
"_0f";
break;
3408 case '#': result+=
"_0g";
break;
3409 case '"': result+=
"_0h";
break;
3410 case '~': result+=
"_0i";
break;
3411 case '\'': result+=
"_0j";
break;
3412 case ';': result+=
"_0k";
break;
3413 case '`': result+=
"_0l";
break;
3417 bool doEscape =
true;
3418 if (allowUnicodeNames)
3431 unsigned char id =
static_cast<unsigned char>(c);
3440 else if (caseSenseNames || !isupper(c))
3447 result+=
static_cast<char>(tolower(c));
3461 const char *p = s.
data();
3471 case '_': result+=c; p++;
break;
3472 case '1': result+=
':'; p++;
break;
3473 case '2': result+=
'/'; p++;
break;
3474 case '3': result+=
'<'; p++;
break;
3475 case '4': result+=
'>'; p++;
break;
3476 case '5': result+=
'*'; p++;
break;
3477 case '6': result+=
'&'; p++;
break;
3478 case '7': result+=
'|'; p++;
break;
3479 case '8': result+=
'.'; p++;
break;
3480 case '9': result+=
'!'; p++;
break;
3484 case '0': result+=
','; p+=2;
break;
3485 case '1': result+=
' '; p+=2;
break;
3486 case '2': result+=
'{'; p+=2;
break;
3487 case '3': result+=
'}'; p+=2;
break;
3488 case '4': result+=
'?'; p+=2;
break;
3489 case '5': result+=
'^'; p+=2;
break;
3490 case '6': result+=
'%'; p+=2;
break;
3491 case '7': result+=
'('; p+=2;
break;
3492 case '8': result+=
')'; p+=2;
break;
3493 case '9': result+=
'+'; p+=2;
break;
3494 case 'a': result+=
'='; p+=2;
break;
3495 case 'b': result+=
'$'; p+=2;
break;
3496 case 'c': result+=
'\\'; p+=2;
break;
3497 case 'd': result+=
'@'; p+=2;
break;
3498 case 'e': result+=
']'; p+=2;
break;
3499 case 'f': result+=
'['; p+=2;
break;
3500 case 'g': result+=
'#'; p+=2;
break;
3501 case 'h': result+=
'"'; p+=2;
break;
3502 case 'i': result+=
'~'; p+=2;
break;
3503 case 'j': result+=
'\''; p+=2;
break;
3504 case 'k': result+=
';'; p+=2;
break;
3505 case 'l': result+=
'`'; p+=2;
break;
3512 if (!caseSenseNames && c>=
'a' && c<=
'z')
3514 result+=
static_cast<char>(toupper(*p));
3545 if (name.
isEmpty())
return name;
3568 size_t resultLen = result.
length();
3572 uint8_t md5_sig[16];
3574 MD5Buffer(result.
data(),
static_cast<unsigned int>(resultLen),md5_sig);
3575 MD5SigToString(md5_sig,sigStr);
3576 result=result.
left(128-32)+sigStr;
3581 int l1Dir=0,l2Dir=0;
3582 int createSubdirsLevel =
Config_getInt(CREATE_SUBDIRS_LEVEL);
3583 int createSubdirsBitmaskL2 = (1<<createSubdirsLevel)-1;
3586 uint8_t md5_sig[16];
3587 MD5Buffer(result.
data(),
static_cast<unsigned int>(result.
length()),md5_sig);
3588 l1Dir = md5_sig[14] & 0xf;
3589 l2Dir = md5_sig[15] & createSubdirsBitmaskL2;
3600 const int sig_size=16;
3601 uint8_t md5_sig[sig_size];
3602 MD5Buffer(fn.
data(),
static_cast<unsigned int>(fn.
length()),md5_sig);
3603 char result[sig_size*3+2];
3606 for (
int i=0;i<sig_size;i++)
3608 static const char oct[]=
"01234567";
3609 uint8_t
byte = md5_sig[i];
3610 *p++=oct[(
byte>>6)&7];
3611 *p++=oct[(
byte>>3)&7];
3612 *p++=oct[(
byte>>0)&7];
3642 QCString absIncFileName = incFileName;
3652 else if (searchIncludes)
3655 for (
const auto &incPath : includePath)
3674 return absIncFileName;
3684 int createSubdirsLevelPow2 = 1 <<
Config_getInt(CREATE_SUBDIRS_LEVEL);
3685 for (
int l1=0; l1<16; l1++)
3691 term(
"Failed to create output directory '{}'\n",subdir);
3693 for (
int l2=0; l2<createSubdirsLevelPow2; l2++)
3696 subsubdir.
sprintf(
"d%x/d%02x",l1,l2);
3699 term(
"Failed to create output directory '{}'\n",subsubdir);
3711 int createSubdirsLevelPow2 = 1 <<
Config_getInt(CREATE_SUBDIRS_LEVEL);
3712 for (
int l1=0;l1<16;l1++)
3716 for (
int l2=0; l2 < createSubdirsLevelPow2; l2++)
3719 subsubdir.
sprintf(
"d%x/d%02x",l1,l2);
3738 bool allowEmptyClass)
3745 namespaceName=nd->
name();
3749 p=
static_cast<int>(clName.
length())-2;
3750 while (p>=0 && (i=clName.
findRev(
"::",p))!=-1)
3757 namespaceName=nd->
name();
3766 className=scopeName;
3767 namespaceName.
clear();
3770 if (className.
isEmpty() && !namespaceName.
isEmpty() && !allowEmptyClass)
3773 className=namespaceName;
3774 namespaceName.
clear();
3780 className = className.
left(className.
length()-2);
3821 int l =
static_cast<int>(result.
length());
3824 bool skipBracket=
FALSE;
3831 while (p>=0 && count>=0)
3833 char c=result.
at(p);
3839 if (p>0 && result.
at(p-1)==
':' && (count==0 || skipBracket))
3841 return result.
right(l-p-1);
3852 if (p>0 && result.
at(p-1)==
'>')
3860 bool foundMatch=
false;
3861 while (p>=0 && !foundMatch)
3873 if (round==0) count++;
3880 if (result.
at(p-1) ==
'<')
3887 foundMatch = count==0;
3902 done = count==0 || skipBracket;
3916 const char *p = s.
data();
3922 if ((c>=
'0' && c<=
'9') || (c>=
'a' && c<=
'z') || (c>=
'A' && c<=
'Z') || c==
'-')
3924 if (first && c>=
'0' && c<=
'9') result+=
'a';
3930 encChar[1]=
hex[
static_cast<unsigned char>(c)>>4];
3931 encChar[2]=
hex[
static_cast<unsigned char>(c)&0xF];
3956 const char *p = s.
data();
3962 case '<': result+=
"<";
break;
3963 case '>': result+=
">";
break;
3964 case '&':
if (keepEntities)
3970 if (ce==
';' || (!(
isId(ce) || ce==
'#')))
break;
3976 while (p<e) result+=*p++;
3992 case '\'': result+=
"'";
break;
3993 case '"': result+=
""";
break;
3994 case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
3995 case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
3996 case 19:
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
case 26:
3997 case 27:
case 28:
case 29:
case 30:
case 31:
3999 default: result+=c;
break;
4011 const char *p=s.
data();
4017 case '<': result+=
"<";
break;
4018 case '>': result+=
">";
break;
4019 case '&':
if (keepEntities)
4025 if (ce==
';' || (!(
isId(ce) || ce==
'#')))
break;
4031 while (p<e) result+=*p++;
4043 case '\'': result+=
"'";
break;
4044 case '"': result+=
""";
break;
4047 uint8_t uc =
static_cast<uint8_t
>(c);
4048 if (uc<32 && !isspace(c))
4052 result+=
hex[uc&0xF];
4071 const char *p=s.
data();
4077 case '"':
if (!singleQuotes) result+=
"\\\"";
else result+=c;
4079 case '\'':
if (singleQuotes) result+=
"\\\'";
else result+=c;
4081 case '\\':
if (*p==
'u' && *(p+1)==
'{') result+=
"\\";
4082 else result+=
"\\\\";
4084 default: result+=c;
break;
4094 std::string s = str.
data();
4095 static const reg::Ex re(R
"(&\a\w*;)");
4101 size_t p=0, i=0, l=0;
4102 for (; it!=
end ; ++it)
4104 const auto &match = *it;
4105 p = match.position();
4109 result+=s.substr(i,p-i);
4113 const char *code=
nullptr;
4124 result+=s.substr(i);
4144 ASSERT(context!=
nullptr);
4146 if (ml==
nullptr)
return;
4148 struct MoveMemberInfo
4151 : memberDef(md), memberGroup(mg), sli(rv) {}
4156 std::vector<MoveMemberInfo> movedMembers;
4158 for (
const auto &md : *ml)
4160 if (md->isEnumerate())
4162 for (
const auto &fmd : md->enumFieldList())
4164 int groupId=fmd->getMemberGroupId();
4170 const auto &info = it->second;
4171 auto mg_it = std::find_if(pMemberGroups->begin(),
4172 pMemberGroups->end(),
4173 [&groupId](
const auto &g)
4174 { return g->groupId()==groupId; }
4177 if (mg_it==pMemberGroups->end())
4179 auto mg = std::make_unique<MemberGroup>(
4188 pMemberGroups->push_back(std::move(mg));
4192 mg_ptr = (*mg_it).get();
4204 int groupId=md->getMemberGroupId();
4210 const auto &info = it->second;
4211 auto mg_it = std::find_if(pMemberGroups->begin(),
4212 pMemberGroups->end(),
4213 [&groupId](
const auto &g)
4214 { return g->groupId()==groupId; }
4217 if (mg_it==pMemberGroups->end())
4219 auto mg = std::make_unique<MemberGroup>(
4228 pMemberGroups->push_back(std::move(mg));
4232 mg_ptr = (*mg_it).get();
4234 movedMembers.emplace_back(md,mg_ptr,info->m_sli);
4240 for (
const auto &mmi : movedMembers)
4242 ml->
remove(mmi.memberDef);
4243 mmi.memberGroup->insertMember(mmi.memberDef->resolveAlias());
4244 mmi.memberGroup->setRefItems(mmi.sli);
4260 AUTO_TRACE(
"type='{}' pos={} name='{}' lang={}",type,pos,name,lang);
4261 static const reg::Ex re_norm(R
"(\a[\w:]*)");
4262 static const reg::Ex re_fortran(R
"(\a[\w:()=]*)");
4272 size_t typeLen=type.
length();
4275 if (lang == SrcLangExt::Fortran)
4287 std::string s = type.
str();
4293 const auto &match = *it;
4294 size_t i = match.position();
4295 size_t l = match.length();
4300 while (ts<typeLen && type[
static_cast<uint32_t
>(ts)]==
' ') { ts++; tl++; }
4301 if (ts<typeLen && type[
static_cast<uint32_t
>(ts)]==
'<')
4306 while (te<typeLen && brCount!=0)
4308 if (type[
static_cast<uint32_t
>(te)]==
'<')
4310 if (te<typeLen-1 && type[
static_cast<uint32_t
>(te)+1]==
'<') te++;
else brCount++;
4312 if (type[
static_cast<uint32_t
>(te)]==
'>')
4314 if (te<typeLen-1 && type[
static_cast<uint32_t
>(te)+1]==
'>') te++;
else brCount--;
4324 pos=
static_cast<int>(i+l+tl);
4328 pos=
static_cast<int>(i+l);
4333 return static_cast<int>(i);
4336 pos =
static_cast<int>(typeLen);
4349 int p=name.
find(
'<');
4350 if (p==-1)
return name;
4354 std::string s = name.
mid(p).
str();
4355 static const reg::Ex re(R
"([\a:][\w:]*)");
4360 for (; it!=
end ; ++it)
4362 const auto &match = *it;
4363 size_t i = match.position();
4364 size_t l = match.length();
4365 result += s.substr(pi,i-pi);
4368 for (
const Argument &formArg : formalArgs)
4370 if (formArg.name == n)
4396 result+=s.substr(pi);
4414 if (formalArgs.
empty())
return nm;
4417 static const reg::Ex re(R
"(\a\w*)");
4418 std::string name = nm.str();
4423 for (; it!=
end ; ++it)
4425 const auto &match = *it;
4426 size_t i = match.position();
4427 size_t l = match.length();
4428 if (i>p) result += name.substr(p,i-p);
4433 actIt = actualArgs->
begin();
4440 for (
auto formIt = formalArgs.
begin();
4441 formIt!=formalArgs.
end() && !found;
4447 if (actualArgs && actIt!=actualArgs->
end())
4454 formArg.
type =
"class";
4459 formArg.
type =
"typename";
4463 formArg.
name +=
"...";
4468 formArg.
name +=
"...";
4475 if (formArg.
name==n && actualArgs && actIt!=actualArgs->
end() && !actArg.
type.
isEmpty())
4482 ii = subst.find(
'<');
4484 if (ii!=-1 &&
static_cast<int>(
prefix.length())>=ii+2 &&
prefix.mid(
prefix.length()-ii-2,ii+1)==subst.left(ii+1))
4489 while ((ii=subst.find(nameArg,pp))!=-1)
4491 bool beforeNonWord = ii==0 || !
isId(subst.at(ii-1));
4492 bool afterNonWord = subst.length()==ii+nameArg.length() || !
isId(subst.at(ii+nameArg.length()));
4493 if (beforeNonWord && afterNonWord)
4497 pp=ii+
static_cast<int>(nameArg.length());
4502 AUTO_TRACE_ADD(
"result={} n={} type={} hasRecursion={}",result,n,actArg.
type,hasRecursion(result,n,actArg.
type));
4503 if (!hasRecursion(result,n,actArg.
type))
4515 result += actArg.
type;
4521 result += actArg.
type+
" "+actArg.
name;
4526 else if (formArg.
name==n &&
4527 (actualArgs==
nullptr || actIt==actualArgs->
end()) &&
4536 else if (formArg.
name==n &&
4537 (actualArgs==
nullptr || actIt==actualArgs->
end()) &&
4545 if (actualArgs && actIt!=actualArgs->
end())
4556 result+=name.substr(p);
4574 bool allowArtificial)
4577 int i=fullName.
find(
'<');
4578 if (i==-1)
return fullName;
4581 int l=
static_cast<int>(fullName.
length());
4588 while (e<l && count>0)
4590 char c=fullName.
at(e++);
4593 case '(': round++;
break;
4594 case ')':
if (round>0) round--;
break;
4595 case '<':
if (round==0) count++;
break;
4596 case '>':
if (round==0) count--;
break;
4601 int si= fullName.
find(
"::",e);
4603 if (parentOnly && si==-1)
break;
4606 result+=fullName.
mid(p,i-p);
4609 if (cd!=
nullptr && (allowArtificial || !cd->
isArtificial()))
4611 result+=fullName.
mid(i,e-i);
4614 else if (pLastScopeStripped)
4617 *pLastScopeStripped=fullName.
mid(i,e-i);
4620 i=fullName.
find(
'<',p);
4622 result+=fullName.
right(l-p);
4639 AUTO_TRACE(
"leftScope='{}' rightScope='{}'",leftScope,rightScope);
4647 int i=0,p=
static_cast<int>(leftScope.
length());
4652 while ((i=leftScope.
findRev(
"::",p))>0)
4656 result = leftScope.
left(i+2)+rightScope;
4684 int sl=
static_cast<int>(s.
length());
4688 if (sp>=sl)
return -1;
4712 while (sp<sl && !done)
4718 case '<': count++;
break;
4719 case '>': count--;
if (count==0) done=
true;
break;
4752 bool newPage =
true;
4757 warn(fileName,startLine,
"multiple use of page label '{}' with different titles, (other occurrence: {}, line: {})",
4841 else if (si->
lineNr() != -1)
4843 warn(orgFile,line,
"multiple use of section label '{}', (first occurrence: {}, line {})",pd->
name(),si->
fileName(),si->
lineNr());
4847 warn(orgFile,line,
"multiple use of section label '{}', (first occurrence: {})",pd->
name(),si->
fileName());
4872 if (!key.
isEmpty() && key[0]!=
'@')
4877 item->setScope(scope);
4878 item->setName(name);
4879 item->setTitle(title);
4880 item->setArgs(args);
4881 item->setGroup(key);
4929 if (!first) { ol.
writeString(
" | "); }
else first=
false;
4941 if (!first) { ol.
writeString(
" | "); }
else first=
false;
4967 int i_fs = fName.
findRev(
'/');
4968 int i_bs = fName.
findRev(
'\\');
4969 int i = fName.
find(
'.',std::max({ i_fs, i_bs ,0}));
4997 result=result.
mid(i+1);
5002 result=result.
mid(i+1);
5015 if (str.
isEmpty() || word==
nullptr)
return false;
5016 static const reg::Ex re(R
"(\a+)");
5017 std::string s = str.str();
5020 if (it->str()==word)
return true;
5031 static reg::Ex re(R
"(\s*(<\a+>)\s*)");
5032 std::string s = sentence.str();
5038 for ( ; it!=
end ; ++it)
5040 const auto match = *it;
5041 std::string part = match[1].str();
5044 size_t i = match.position();
5045 size_t l = match.length();
5046 result+=s.substr(p,i-p);
5047 result+=match.str();
5053 size_t i = match[1].position();
5054 size_t l = match[1].length();
5055 result+=s.substr(p,i-p);
5059 result+=s.substr(p);
5075 const char *p = s.
data();
5078 int i=0,li=-1,l=
static_cast<int>(s.
length());
5082 if (c==
' ' || c==
'\t' || c==
'\r') { i++; p++; }
5083 else if (c==
'\\' &&
literal_at(p,
"\\ilinebr")) { i+=8; li=i; p+=8; }
5084 else if (c==
'\n') { i++; li=i; docLine++; p++; }
5094 if (c==
' ' || c==
'\t' || c==
'\r') { b--; p--; }
5095 else if (c==
'r' && b>=7 &&
literal_at(p-7,
"\\ilinebr")) { bi=b-7; b-=8; p-=8; }
5096 else if (c==
'>' && b>=11 &&
literal_at(p-11,
"\\ilinebr<br>")) { bi=b-11; b-=12; p-=12; }
5097 else if (c==
'\n') { bi=b; b--; p--; }
5102 if (li==-1 && bi==-1)
return s;
5109 return s.
mid(li,bi-li);
5127 {
"idl",
"c", SrcLangExt::IDL,
".idl" },
5128 {
"java",
"c", SrcLangExt::Java,
".java"},
5129 {
"javascript",
"c", SrcLangExt::JS,
".js" },
5130 {
"csharp",
"c", SrcLangExt::CSharp,
".cs" },
5131 {
"d",
"c", SrcLangExt::D,
".d" },
5132 {
"php",
"c", SrcLangExt::PHP,
".php" },
5133 {
"objective-c",
"c", SrcLangExt::ObjC,
".m" },
5134 {
"c",
"c", SrcLangExt::Cpp,
".c" },
5135 {
"c++",
"c", SrcLangExt::Cpp,
".cpp" },
5136 {
"slice",
"c", SrcLangExt::Slice,
".ice" },
5137 {
"python",
"python", SrcLangExt::Python,
".py" },
5138 {
"fortran",
"fortran", SrcLangExt::Fortran,
".f" },
5139 {
"fortranfree",
"fortranfree", SrcLangExt::Fortran,
".f90" },
5140 {
"fortranfixed",
"fortranfixed", SrcLangExt::Fortran,
".f" },
5141 {
"vhdl",
"vhdl", SrcLangExt::VHDL,
".vhdl"},
5142 {
"xml",
"xml", SrcLangExt::XML,
".xml" },
5143 {
"sql",
"sql", SrcLangExt::SQL,
".sql" },
5144 {
"md",
"md", SrcLangExt::Markdown,
".md" },
5145 {
"lex",
"lex", SrcLangExt::Lex,
".l" },
5152 [&langName](
const auto &info) { return info.langName==langName; });
5159 if (extName.
at(0)!=
'.') extName.
prepend(
".");
5169 err(
"Failed to assign extension {} to parser {} for language {}\n",
5170 extName.
data(),it1->parserName,language);
5258 if (extName.
isEmpty()) extName=
".no_extension";
5259 if (extName.
at(0)!=
'.') extName.
prepend(
".");
5275 if (lang == SrcLangExt::Unknown)
5279 if (langName.
at(0)==
'.') langName = langName.
mid(1);
5281 [&langName](
const auto &info) { return info.langName==langName; });
5284 lang = it->parserId;
5285 fileName = it->defExt;
5289 return SrcLangExt::Cpp;
5298 int lastDot = fn.
findRev(
'.');
5299 if (lastDot!=-1)
return fn.
mid(lastDot);
5308 if (scope==
nullptr ||
5328 if (qualifierIndex!=-1)
5330 explicitScopePart = name.
left(qualifierIndex);
5332 name = name.
mid(qualifierIndex+2);
5336 int minDistance = 10000;
5345 if (distance!=-1 && distance<minDistance)
5347 minDistance = distance;
5361 if (bestMatch && bestMatch->
isTypedef())
5369 if (startPos>=len)
return len;
5370 uint8_t c =
static_cast<uint8_t
>(utf8Str[startPos]);
5375 int (*matcher)(int) =
nullptr;
5376 c =
static_cast<uint8_t
>(utf8Str[startPos+bytes]);
5380 c =
static_cast<uint8_t
>(utf8Str[startPos+bytes]);
5384 matcher = std::isxdigit;
5388 matcher = std::isdigit;
5391 else if (std::isalnum(c))
5394 matcher = std::isalnum;
5398 while ((c =
static_cast<uint8_t
>(utf8Str[startPos+bytes]))!=0 && matcher(c))
5408 return startPos+bytes;
5425 .setAutolinkSupport(
false))
5427 auto astImpl =
dynamic_cast<const DocNodeAST*
>(ast.get());
5431 std::visit(visitor,astImpl->root);
5436 int l=
static_cast<int>(result.
length());
5440 if (charCnt>=80)
break;
5447 if (result.
at(i)==
',' ||
5448 result.
at(i)==
'.' ||
5449 result.
at(i)==
'!' ||
5450 result.
at(i)==
'?' ||
5458 if ( i < l) result=result.
left(i)+
"...";
5459 return result.
data();
5478 auto astImpl =
dynamic_cast<const DocNodeAST*
>(ast.get());
5486 std::visit(visitor,astImpl->root);
5503 if (al.
empty())
return;
5520 .setIndexWords(
true));
5530#ifdef TRACINGSUPPORT
5531 void *backtraceFrames[128];
5532 int frameCount = backtrace(backtraceFrames, 128);
5533 const size_t cmdLen = 40960;
5534 static char cmd[cmdLen];
5536 p +=
qsnprintf(p,cmdLen,
"/usr/bin/atos -p %d ", (
int)getpid());
5537 for (
int x = 0; x < frameCount; x++)
5539 p +=
qsnprintf(p,cmdLen,
"%p ", backtraceFrames[x]);
5541 fprintf(stderr,
"========== STACKTRACE START ==============\n");
5545 while (
size_t len = fread(resBuf, 1,
sizeof(resBuf), fp))
5547 fwrite(resBuf, 1, len, stderr);
5551 fprintf(stderr,
"============ STACKTRACE END ==============\n");
5560 if (
qstricmp(inputEncoding,outputEncoding)==0)
return;
5562 if (cd==
reinterpret_cast<void *
>(-1))
5564 term(
"unsupported character conversion: '{}'->'{}': {}\n"
5565 "Check the INPUT_ENCODING setting in the config file!\n",
5566 inputEncoding,outputEncoding,strerror(errno));
5568 size_t iLeft = contents.size();
5569 const char *srcPtr = contents.data();
5570 size_t tmpBufSize = contents.size()*4+1;
5571 size_t oLeft = tmpBufSize;
5573 tmpBuf.resize(tmpBufSize);
5574 char *dstPtr = tmpBuf.data();
5578 newSize = tmpBufSize-oLeft;
5579 tmpBuf.resize(newSize);
5580 std::swap(contents,tmpBuf);
5585 term(
"{}: failed to translate characters from {} to {}: check INPUT_ENCODING\n",
5586 fileName,inputEncoding,outputEncoding);
5598 if (filterName.
isEmpty() || !filter)
5603 err(
"could not open file {}\n",fileName);
5607 auto fileSize = fi.
size();
5608 contents.resize(fileSize);
5609 f.read(contents.data(),fileSize);
5612 err(
"problems while reading file {}\n",fileName);
5618 QCString cmd=filterName+
" \""+fileName+
"\"";
5623 err(
"could not execute filter {}\n",filterName);
5626 const int bufSize=4096;
5629 while ((numRead=
static_cast<int>(fread(buf,1,bufSize,f)))>0)
5632 contents.append(buf,numRead);
5639 if (contents.size()>=2 &&
5640 static_cast<uint8_t
>(contents[0])==0xFF &&
5641 static_cast<uint8_t
>(contents[1])==0xFE
5646 else if (contents.size()>=2 &&
5647 static_cast<uint8_t
>(contents[0])==0xFE &&
5648 static_cast<uint8_t
>(contents[1])==0xFF
5653 else if (contents.size()>=3 &&
5654 static_cast<uint8_t
>(contents[0])==0xEF &&
5655 static_cast<uint8_t
>(contents[1])==0xBB &&
5656 static_cast<uint8_t
>(contents[2])==0xBF
5659 contents.erase(0,3);
5675 std::string t = title.
str();
5676 static const reg::Ex re(R
"(%[a-z_A-Z]+)");
5680 for (; it!=
end ; ++it)
5682 const auto &match = *it;
5683 size_t i = match.position();
5684 size_t l = match.length();
5685 if (i>p) tf+=t.substr(p,i-p);
5686 tf+=match.str().substr(1);
5695template<
class PatternList,
class PatternElem,
typename PatternGet = QCString(*)(const PatternElem &)>
5697 const PatternList &patList,
5704 if (!patList.empty())
5710 for (
const auto &li : patList)
5712 std::string pattern = getter(li).str();
5713 if (!pattern.empty())
5715 size_t i=pattern.find(
'=');
5716 if (i!=std::string::npos) pattern=pattern.substr(0,i);
5718 if (!caseSenseNames)
5749 auto getter = [](std::string s) ->
QCString {
return s; };
5770 if (extLinksInWindow)
5771 return "target=\"_blank\" ";
5773 return "target=\"_parent\" ";
5790 if (!targetFileName.
isEmpty())
5795 if (!anchor.
isEmpty() && isLocalFile)
5823 result = it->second;
5824 size_t l = result.
length();
5825 if (!relPath.
isEmpty() && l>0 && result.
at(0)==
'.')
5830 if (l>0 && result.
at(l-1)!=
'/') result+=
'/';
5831 if (!href) result.
append(
"\" ");
5850 std::string s=str.
str();
5851 static const reg::Ex re(R
"(##[0-9A-Fa-f][0-9A-Fa-f])");
5857 size_t sl=s.length();
5859 for (; it!=
end ; ++it)
5861 const auto &match = *it;
5862 size_t i = match.position();
5863 size_t l = match.length();
5864 if (i>p) result+=s.substr(p,i-p);
5865 std::string lumStr = match.str().substr(2);
5866#define HEXTONUM(x) (((x)>='0' && (x)<='9') ? ((x)-'0') : \
5867 ((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \
5868 ((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0)
5870 double r = 0,g = 0,b = 0;
5873 pow(level/255.0,gamma/100.0),&r,&g,&b);
5874 int red =
static_cast<int>(r*255.0);
5875 int green =
static_cast<int>(g*255.0);
5876 int blue =
static_cast<int>(b*255.0);
5879 colStr[1]=
hex[red>>4];
5880 colStr[2]=
hex[red&0xf];
5881 colStr[3]=
hex[green>>4];
5882 colStr[4]=
hex[green&0xf];
5883 colStr[5]=
hex[blue>>4];
5884 colStr[6]=
hex[blue&0xf];
5890 if (p<sl) result+=s.substr(p);
5901 err(
"could not copy file {} to {}\n",src,dest);
5915 int m1 = text.
find(marker);
5916 if (m1==-1)
return result;
5921 while (!found && (i=text.
find(
'\n',p))!=-1)
5923 found = (p<=m1 && m1<i);
5939 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp || lang==SrcLangExt::VHDL || lang==SrcLangExt::Python)
5943 else if (lang==SrcLangExt::PHP && !classScope)
5955 static const std::unordered_set<std::string> schemes = {
5956 "http",
"https",
"ftp",
"ftps",
"sftp",
"file",
"news",
"irc",
"ircs"
5959 int colonPos = loc_url.
find(
':');
5960 return colonPos!=-1 && schemes.find(loc_url.
left(colonPos).
str())!=schemes.end();
5982 return (prot!=Protection::Private && prot!=Protection::Package) ||
5983 (prot==Protection::Private && extractPrivate) ||
5984 (prot==Protection::Package && extractPackage);
5995 const char *p=s.
data();
5998 int minIndent=1000000;
5999 bool searchIndent=
true;
6001 bool skipFirst = skipFirstLine;
6004 if (c==
'\t') { indent+=tabSize - (indent%tabSize); }
6005 else if (c==
'\n') { indent=0; searchIndent=
true; skipFirst=
false; }
6006 else if (c==
' ') { indent++; }
6007 else if (searchIndent && !skipFirst)
6010 if (indent<minIndent) minIndent=indent;
6015 if (minIndent==0)
return substitute(s,
"@ilinebr",
"\\ilinebr");
6021 skipFirst=skipFirstLine;
6030 else if (indent<minIndent && !skipFirst)
6034 int newIndent = indent+tabSize-(indent%tabSize);
6048 else if (c==
'\\' &&
literal_at(p,
"ilinebr "))
6051 result <<
"\\ilinebr ";
6054 for (
int j=0;j<minIndent;j++)
if (*(p+j)==
' ') skipAmount++;
6055 if (skipAmount==minIndent)
6062 result <<
"\\ilinebr";
6073 return result.
str();
6081 if (indentationLevel <= 0 || doc.
isEmpty())
return;
6086 const char *src = doc.
data();
6088 bool insideIndent = !skipFirstLine;
6090 if (!skipFirstLine) cnt = indentationLevel;
6098 insideIndent =
true;
6099 cnt = indentationLevel;
6110 insideIndent =
false;
6120 insideIndent =
false;
6125 doc.
resize(
static_cast<uint32_t
>(dst-doc.
data()));
6134 return ( ((allExternals && fd->
isLinkable()) ||
6152uint32_t getUtf8Code(
const QCString& s,
int idx )
6154 const int length = s.
length();
6155 if (idx >= length) {
return 0; }
6156 const uint32_t c0 = (uint8_t)s.
at(idx);
6157 if ( c0 < 0xC2 || c0 >= 0xF8 )
6161 if (idx+1 >= length) {
return 0; }
6162 const uint32_t c1 = ((uint8_t)s.
at(idx+1)) & 0x3f;
6165 return ((c0 & 0x1f) << 6) | c1;
6167 if (idx+2 >= length) {
return 0; }
6168 const uint32_t c2 = ((uint8_t)s.
at(idx+2)) & 0x3f;
6171 return ((c0 & 0x0f) << 12) | (c1 << 6) | c2;
6173 if (idx+3 >= length) {
return 0; }
6175 const uint32_t c3 = ((uint8_t)s.
at(idx+3)) & 0x3f;
6176 return ((c0 & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3;
6188uint32_t getUtf8CodeToLower(
const QCString& s,
int idx )
6190 const uint32_t v = getUtf8Code( s, idx );
6191 return v < 0x7f ? tolower( v ) : v;
6203uint32_t getUtf8CodeToUpper(
const QCString& s,
int idx )
6205 const uint32_t v = getUtf8Code( s, idx );
6206 return v < 0x7f ? toupper( v ) : v;
6220 std::string s = docs.
str();
6221 static const reg::Ex re(R
"(\[([ inout,]+)\])");
6226 const auto &match = *it;
6227 size_t p = match.position();
6228 size_t l = match.length();
6232 std::string dir = match[1].str();
6234 dir.erase(std::remove_if(dir.begin(),dir.end(),
6235 [](
const char c) { return c==
' ' || c==
','; }
6237 unsigned char ioMask=0;
6238 size_t inIndex = dir.find(
"in");
6239 if ( inIndex!=std::string::npos) { dir.erase( inIndex,2); ioMask|=(1<<0); }
6240 size_t outIndex = dir.find(
"out");
6241 if (outIndex!=std::string::npos) { dir.erase(outIndex,3); ioMask|=(1<<1); }
6242 if (dir.empty() && ioMask!=0)
6245 if (ioMask==((1<<0)|(1<<1)))
return "[in,out]";
6246 else if (ioMask==(1<<0))
return "[in]";
6247 else if (ioMask==(1<<1))
return "[out]";
6279 *outListType1=inListType;
6282 if (inProt==Protection::Public)
6289 else if (inProt==Protection::Protected)
6297 *outListType2=inListType.
toPublic();
6300 else if (inProt==Protection::Private)
6310 *outListType1=inListType.
toPublic();
6332 int i= imgExt.
find(
':');
6333 return i==-1 ? imgExt : imgExt.
left(i);
6338 assert(!f.is_open());
6339 bool fileOpened=
FALSE;
6340 bool writeToStdout=outFile==
"-";
6343 f.basic_ios<char>::rdbuf(std::cout.rdbuf());
6358 fileOpened = f.is_open();
6365 static const std::unordered_set<std::string> fortran_C_keywords = {
6366 "character",
"call",
"close",
"common",
"continue",
6367 "case",
"contains",
"cycle",
"class",
"codimension",
6368 "concurrent",
"contiguous",
"critical"
6371 if (*contents !=
'c' && *contents !=
'C')
return false;
6373 const char *c = contents;
6375 while (*c && *c !=
' ') {keyword += *c; c++;}
6376 keyword = keyword.
lower();
6378 return (fortran_C_keywords.find(keyword.
str()) != fortran_C_keywords.end());
6386 bool skipLine=
FALSE;
6392 size_t sizCont = contents.
length();
6393 for (
size_t i=0;i<sizCont;i++)
6397 switch(contents.
at(i))
6404 column += tabSize-1;
6421 if (column==1)
return TRUE;
6422 if (skipLine)
break;
6425 if (column!=6) skipLine=
TRUE;
6428 if (skipLine)
break;
6429 if (column>=7)
return TRUE;
6454 auto skipBlock = [&markerInfo](
const char *p,
const SelectionBlock &blk)
6461 size_t len = markerInfo.
endLen;
6462 bool negate = *(p+markerInfo.
endLen)==
'!';
6464 size_t blkNameLen =
qstrlen(blk.name);
6465 if (
qstrncmp(p+len,blk.name,blkNameLen)==0 &&
6469 return p+len+blkNameLen+markerInfo.
closeLen;
6486 const char *p = s.
data();
6496 bool negate = *(p+len)==
'!';
6498 for (
const auto &blk : blockList)
6500 size_t blkNameLen =
qstrlen(blk.name);
6501 if (
qstrncmp(p+len,blk.name,blkNameLen)==0 &&
6504 bool blockEnabled = blk.enabled!=negate;
6506 p+=len+blkNameLen+markerInfo.
closeLen;
6525 size_t len = markerInfo.
endLen;
6526 bool negate = *(p+len)==
'!';
6528 for (
const auto &blk : blockList)
6530 size_t blkNameLen =
qstrlen(blk.name);
6531 if (
qstrncmp(p+len,blk.name,blkNameLen)==0 &&
6535 p+=len+blkNameLen+markerInfo.
closeLen;
6566 const char *p = s.
data();
6575 bool negate = *(p+len)==
'!';
6581 if (markerInfo.
closeLen==0 && *p==
'\n')
6583 warn(fileName,-1,
"Remaining begin replacement with marker '{}'",marker);
6589 warn(fileName,-1,
"Remaining begin replacement with marker '{}'",marker);
6598 size_t len = markerInfo.
endLen;
6599 bool negate = *(p+len)==
'!';
6605 if (markerInfo.
closeLen==0 && *p==
'\n')
6607 warn(fileName,-1,
"Remaining end replacement with marker '{}'",marker);
6613 warn(fileName,-1,
"Remaining end replacement with marker '{}'",marker);
6630 const char *p=s.
data();
6639 while (*e==
' ' || *e==
'\t') e++;
6661 size_t prev = 0, pos = 0, len = s.length();
6664 pos = s.find(delimiter, prev);
6665 if (pos == std::string::npos) pos = len;
6666 if (pos>prev) result.push_back(s.substr(prev,pos-prev));
6667 prev = pos + delimiter.length();
6669 while (pos<len && prev<len);
6681 for ( ; iter !=
end; ++iter)
6683 const auto &match = *iter;
6684 size_t i=match.position();
6685 size_t l=match.length();
6686 if (i>p) result.push_back(s.substr(p,i-p));
6689 if (p<s.length()) result.push_back(s.substr(p));
6696 auto it = std::find(sv.begin(),sv.end(),s);
6697 return it!=sv.end() ?
static_cast<int>(it-sv.begin()) : -1;
6705 return reg::search(s,match,re) ?
static_cast<int>(match.position()) : -1;
6713 for (
const auto &s : sv)
6715 if (!first) result+=delimiter;
6729 while (residual > 0)
6731 modVal[0] = (upper ?
'A':
'a') + (residual-1)%26;
6732 result = modVal + result;
6733 residual = (residual-1) / 26;
6740 static const char *str_romans_upper[] = {
"M",
"CM",
"D",
"CD",
"C",
"XC",
"L",
"XL",
"X",
"IX",
"V",
"IV",
"I" };
6741 static const char *str_romans_lower[] = {
"m",
"cm",
"d",
"cd",
"c",
"xc",
"l",
"xl",
"x",
"ix",
"v",
"iv",
"i" };
6742 static const int values[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
6743 static const char **str_romans = upper ? str_romans_upper : str_romans_lower;
6748 for (
int i = 0; i < 13; ++i)
6750 while (residual - values[i] >= 0)
6752 result += str_romans[i];
6753 residual -= values[i];
6763 size_t size = s.
length();
6766 const char *data = s.
data();
6769 constexpr auto doxy_nbsp =
"&_doxy_nbsp;";
6770 const int maxIndent=1000000;
6771 int minIndent=maxIndent;
6780 int stop = tabSize - (col%tabSize);
6783 while (stop--) result+=
' ';
6787 if (data[i] ==
'\\')
6793 else if (i+5<size &&
literal_at(data+i,
"iskip"))
6798 else if (i+8<size &&
literal_at(data+i,
"endiskip"))
6830 for (
int j=0;j<bytes-1 && c;j++)
6842 if (!skip && col<minIndent) minIndent=col;
6846 if (minIndent!=maxIndent) refIndent=minIndent;
else refIndent=0;
6855 uint8_t md5_sig[16];
6857 MD5Buffer(projectCookie.
data(),
static_cast<unsigned int>(projectCookie.
length()),md5_sig);
6858 MD5SigToString(md5_sig,sigStr);
6859 sigStr[32]=
'_'; sigStr[33]=0;
6866 int l =
static_cast<int>(name.
length());
6867 int lastSepPos = -1;
6868 const char *p = name.
data();
6877 if (sharpCount==0 && p[i+1]==
':' && p[i+2]==
':')
6891 if (ts==-1) ts=0;
else p+=++ts;
6892 for (i=ts;i<l-1;i++)
6895 if (c==
':' && *p==
':') lastSepPos=i;
6930 case '\t': col+=tabSize - (col%tabSize);
6939 for (
int i=0;i<numBytes-1 && (c=*s++);i++) {}
6940 if (c==0)
return col;
6955 int idx = name.
find(
'<');
6968 int idx = result.
find(
'-');
6969 result = result.
left(idx)+templArgs;
6977 int i = text.
find(
'"');
7001 uint8_t md5_sig[16];
7003 MD5Buffer(content.
data(),
static_cast<unsigned int>(content.
length()),md5_sig);
7004 MD5SigToString(md5_sig,sigStr);
7006 QCString fileName = baseName + sigStr + extension;
7016 file.write( content.
data(), content.
length() );
7021 err(
"Could not open file {} for writing\n",fileName);
7042template <
typename T,
typename =
void>
7045template <
typename T>
7046struct has_insertion_op< T, std::void_t<decltype(std::declval<T&>() << std::declval<const QCString &>())> > : std::true_type {};
7048template <typename T>
7049inline constexpr bool has_insertion_op_v = has_insertion_op<T>::value;
7052const char *writeHtmlEntity(T &result, const char *s, HtmlEntityMapperFunc &&mapper, const char *fallback)
7056 const char *q = s+1;
7058 while ((*q >= 'a' && *q <= 'z') || (*q >= 'A' && *q <= 'Z') || (*q >= '0' && *q <= '9'))
7065 HtmlEntityMapper::SymType res = HtmlEntityMapper::instance().name2sym(QCString(s).left(cnt));
7066 if (res!=HtmlEntityMapper::Sym_Unknown)
7068 if constexpr (has_insertion_op_v<T>)
7070 result << mapper(res);
7074 result += mapper(res);
7079 if constexpr (has_insertion_op_v<T>)
7091template const char *writeHtmlEntity<QCString>(QCString& t, const char *s, HtmlEntityMapperFunc &&mapper, const char *fallback);
7092template const char *writeHtmlEntity<TextStream>(TextStream& t, const char *s, HtmlEntityMapperFunc &&mapper, const char *fallback);
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.
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.
SymType name2sym(const QCString &symName) const
Give code of the requested HTML entity name.
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 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 lineBreak(const QCString &style=QCString())
void parseText(const QCString &textStr)
void writeNonBreakableSpace(int num)
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
QCString getParserName(const QCString &extension)
Gets the name of the parser associated with given extension.
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
const VectorPtr & find(const QCString &name)
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. an enum) this method will return it.
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.
virtual QCString trWriteList(int numEntries)=0
virtual QCString trISOLang()=0
virtual QCString trTypeConstraints()=0
virtual QCString trPageAbbreviation()=0
virtual QCString trModule(bool first_capital, bool singular)=0
virtual QCString trOverloadText()=0
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.
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 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)
QCString linkToText(SrcLangExt lang, const QCString &link, bool ignoreDots)
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 const DirDef * resolveDirLink(const QCString &linkRef)
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, const bool citeEntry)
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[]
const char * writeHtmlEntity(T &result, const char *s, HtmlEntityMapperFunc &&mapper, const char *fallback)
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