26 #include <qfileinfo.h>
28 #include <qdatetime.h>
66 #define ENABLE_TRACINGSUPPORT 0
68 #if defined(_OS_MAC_) && ENABLE_TRACINGSUPPORT
69 #define TRACINGSUPPORT
89 #define MAP_ALGO ALGO_MD5
91 #define REL_PATH_TO_ROOT "../../"
130 for (i=0;i<indent;i++)
137 const char *anchor,
const char *text
167 if (s.isEmpty())
return result;
168 static QRegExp re(
"[ :]*@[0-9]+[: ]*");
169 int i,l,sl=s.length();
171 while ((i=re.match(s,p,&l))!=-1)
173 result+=s.mid(p,i-p);
175 bool b1=FALSE,b2=FALSE;
176 while (c<i+l && s.at(c)!=
'@')
if (s.at(c++)==
':') b1=TRUE;
178 while (c>=i && s.at(c)!=
'@')
if (s.at(c--)==
':') b2=TRUE;
185 result+=s.right(sl-p);
194 if (s.isEmpty())
return result;
195 static QRegExp re(
"@[0-9]+");
196 int i,l,sl=s.length();
198 while ((i=re.match(s,p,&l))!=-1)
200 result+=s.mid(p,i-p);
207 result+=
"__anonymous__";
211 result+=s.right(sl-p);
230 if (!newScope.isEmpty()) newScope+=
"::";
231 newScope+=s.mid(i,l);
236 if (!newScope.isEmpty()) newScope+=
"::";
237 newScope+=s.right(sl-i);
268 const int maxMarkerStrLen = 20;
269 char result[maxMarkerStrLen];
270 qsnprintf(result,maxMarkerStrLen,
"@%d",
id);
277 const char *s=l.first();
279 unsigned int length = 0;
283 if (prefix.length() > length &&
284 qstricmp(path.left(prefix.length()),prefix)==0)
286 length = prefix.length();
287 potential = path.right(path.length()-prefix.length());
291 if (length)
return potential;
317 QCString n=((QCString)name).lower();
318 if (n.right(2)==
".c" ||
320 n.right(4)==
".cxx" ||
321 n.right(4)==
".cpp" ||
322 n.right(4)==
".c++" ||
323 n.right(5)==
".java" ||
328 n.right(4)==
".ixx" ||
329 n.right(4)==
".ipp" ||
330 n.right(4)==
".i++" ||
331 n.right(4)==
".inl" ||
334 if (n.right(2)==
".h" ||
336 n.right(4)==
".hxx" ||
337 n.right(4)==
".hpp" ||
338 n.right(4)==
".h++" ||
339 n.right(4)==
".idl" ||
340 n.right(4)==
".ddl" ||
352 if (qualifiedName.isEmpty())
359 if (typedefContext) *typedefContext=context;
362 int scopeIndex = qualifiedName.findRev(
"::");
363 QCString resName=qualifiedName;
366 resName=qualifiedName.right(qualifiedName.length()-scopeIndex-2);
367 if (resName.isEmpty())
375 while (mContext && md==0)
382 QCString resScopeName = qualifiedName.left(scopeIndex);
390 QCString qualScopePart = resScopeName.mid(is,l);
392 if (!tmp.isEmpty()) qualScopePart=tmp;
395 if (resScope==0)
break;
421 for (;(tmd=mni.current());++mni)
429 if (dist!=-1 && (md==0 || dist<minDist))
449 if (args.find(
")(")!=-1)
453 else if (args.find(
'[')!=-1)
474 if (n==0 || n[0]==
'\0')
return 0;
491 if (name==0 || name[0]==
'\0')
return 0;
504 warn_uncond(
"possible recursive namespace alias detected for %s!\n",name);
522 QCString *pTemplSpec,
523 QCString *pResolvedType
526 const QCString &explicitScopePart);
536 MemberDef **pMemType,QCString *pTemplSpec,
537 QCString *pResolvedType,
562 actTemplParams && actTemplParams->count()>0)
567 QCString typedefValue = type;
568 int tl=type.length();
570 while (ip>=0 && (type.at(ip)==
'*' || type.at(ip)==
'&' || type.at(ip)==
' '))
574 type=type.left(ip+1);
575 type.stripPrefix(
"const ");
576 type.stripPrefix(
"struct ");
577 type.stripPrefix(
"union ");
580 while (sp<tl && type.at(sp)==
' ') sp++;
583 fileScope,type,&memTypeDef,0,pResolvedType);
585 if (memTypeDef && memTypeDef->isTypedef())
590 else if (memTypeDef && memTypeDef->isEnumerate() && pMemType)
592 *pMemType = memTypeDef;
599 int si=type.findRev(
"::");
600 int i=type.find(
'<');
603 if (pTemplSpec) *pTemplSpec = type.mid(i);
605 type.left(i),0,0,pResolvedType);
618 if (pTemplSpec) *pTemplSpec = type.mid(i);
635 if (sp>0) pResolvedType->prepend(typedefValue.left(sp));
636 if (ip<tl-1) pResolvedType->append(typedefValue.right(tl-ip-1));
640 *pResolvedType=typedefValue;
653 pTemplSpec ? *pTemplSpec : QCString(),
654 pResolvedType ? *pResolvedType : QCString()
669 QCString result=name;
670 if (name.isEmpty())
return result;
674 if (di==0)
return result;
682 int minDistance=10000;
683 for (dli.toFirst();(d=dli.current());++dli)
694 if (distance!=-1 && distance<minDistance)
697 minDistance=distance;
722 if (pTypeDef) *pTypeDef=bestMatch;
736 for (cli.toFirst();(cd=cli.current());++cli)
764 QCString qualScopePart =
substTypedef(current,fileScope,path.mid(is,l),&typeDef);
786 ((
NamespaceDef *)current)->getUsedClasses(),qualScopePart);
791 ((
FileDef *)current)->getUsedClasses(),qualScopePart);
794 if (current==0)
break;
811 const QCString &explicitScopePart=
""
819 bool explicitScopePartEmpty = explicitScopePart.isEmpty();
820 for (cli.toFirst();(ucd=cli.current());++cli)
824 if (sc && sc==item)
return TRUE;
834 const QCString &explicitScopePart=
"")
836 static QDict<void> visitedDict;
842 for (nli.toFirst();(und=nli.current());++nli,count++)
846 Definition *sc = explicitScopePart.isEmpty() ? und :
followPath(und,fileScope,explicitScopePart);
852 QCString key=und->
name();
855 visitedDict.insert(key,(
void *)0x08);
863 visitedDict.remove(key);
954 if (accessStack.
find(scope,fileScope,item))
958 accessStack.
push(scope,fileScope,item);
964 bool memberAccessibleFromScope =
970 bool nestedClassInsideBaseClass =
977 if (itemScope==scope || memberAccessibleFromScope || nestedClassInsideBaseClass)
980 if (nestedClassInsideBaseClass) result++;
1027 result= (i==-1) ? -1 : i+2;
1052 Definition *item,
const QCString &explicitScopePart)
1054 if (explicitScopePart.isEmpty())
1061 if (accessStack.
find(scope,fileScope,item,explicitScopePart))
1065 accessStack.
push(scope,fileScope,item,explicitScopePart);
1082 if (itemScope==newScope)
1086 else if (itemScope && newScope &&
1120 for (cli.toFirst();(cd=cli.current());++cli)
1135 for (nli.toFirst();(nd=nli.current());++nli)
1154 item,explicitScopePart);
1157 result = (i==-1) ? -1 : i+2;
1190 item,explicitScopePart);
1192 result= (i==-1) ? -1 : i+2;
1205 int i = name.find(
'<');
1206 return name.findRev(
"::",i==-1 ? name.length() : i);
1212 const QCString &explicitScopePart,
1217 QCString &bestTemplSpec,
1218 QCString &bestResolvedType
1248 if (distance<minDistance)
1250 minDistance=distance;
1253 bestTemplSpec.resize(0);
1256 else if (distance==minDistance &&
1257 fileScope && bestMatch &&
1271 minDistance=distance;
1274 bestTemplSpec.resize(0);
1298 if (distance<minDistance)
1302 minDistance=distance;
1310 bestTemplSpec = spec;
1311 bestResolvedType = type;
1317 bestTypedef = enumType;
1325 bestTemplSpec = spec;
1326 bestResolvedType = type;
1332 bestTemplSpec.resize(0);
1333 bestResolvedType.resize(0);
1349 if (distance<minDistance)
1351 minDistance=distance;
1378 QCString *pTemplSpec,
1379 QCString *pResolvedType
1384 QCString explicitScopePart;
1385 QCString strippedTemplateParams;
1388 &strippedTemplateParams);
1390 if (!strippedTemplateParams.isEmpty())
1397 if (qualifierIndex!=-1)
1400 explicitScopePart=name.left(qualifierIndex);
1403 name=name.mid(qualifierIndex+2);
1431 bool hasUsingStatements =
1444 int scopeNameLen = scope->
name().length()+1;
1445 int nameLen = name.length()+1;
1446 int explicitPartLen = explicitScopePart.length();
1447 int fileScopeLen = hasUsingStatements ? 1+fileScope->
absFilePath().length() : 0;
1451 QCString key(scopeNameLen+nameLen+explicitPartLen+fileScopeLen+1);
1452 char *p=key.rawData();
1453 qstrcpy(p,scope->
name()); *(p+scopeNameLen-1)=
'+';
1455 qstrcpy(p,name); *(p+nameLen-1)=
'+';
1457 qstrcpy(p,explicitScopePart);
1464 if (hasUsingStatements)
1481 if (pTemplSpec) *pTemplSpec=pval->
templSpec;
1482 if (pTypeDef) *pTypeDef=pval->
typeDef;
1498 QCString bestTemplSpec;
1499 QCString bestResolvedType;
1500 int minDistance=10000;
1508 for (dli.toFirst();(d=dli.current());++dli,++count)
1511 minDistance,bestMatch,bestTypedef,bestTemplSpec,
1520 minDistance,bestMatch,bestTypedef,bestTemplSpec,
1526 *pTypeDef = bestTypedef;
1530 *pTemplSpec = bestTemplSpec;
1534 *pResolvedType = bestResolvedType;
1567 QCString *pTemplSpec,
1568 bool mayBeUnlinkable,
1570 QCString *pResolvedType
1573 static bool optimizeOutputVhdl =
Config_getBool(OPTIMIZE_OUTPUT_VHDL);
1591 if (optimizeOutputVhdl)
1605 if (!mayBeUnlinkable && result && !result->
isLinkable())
1607 if (!mayBeHidden || !result->
isHidden())
1625 int b = s.findRev(
"operator",i);
1626 if (b==-1)
return FALSE;
1631 if (!isspace((uchar)s.at(b)))
return FALSE;
1639 int b = s.findRev(
"operator",i);
1640 if (b==-1)
return FALSE;
1645 if (
isId((uchar)s.at(b)))
return FALSE;
1651 static const char constScope[] = {
'c',
'o',
'n',
's',
't',
':' };
1652 static const char virtualScope[] = {
'v',
'i',
'r',
't',
'u',
'a',
'l',
':' };
1653 static const char operatorScope[] = {
'o',
'p',
'e',
'r',
'a',
't',
'o',
'r',
'?',
'?',
'?' };
1701 if (s.isEmpty() || vhdl)
return s;
1705 static char *growBuf = 0;
1706 static int growBufLen = 0;
1707 if (s.length()*3>growBufLen)
1709 growBufLen = s.length()*3;
1710 growBuf = (
char *)realloc(growBuf,growBufLen+1);
1712 if (growBuf==0)
return s;
1714 char *src=s.rawData();
1725 while (i<l && isspace((uchar)src[i]))
1732 char nc=i<l-1 ? src[i+1] :
' ';
1778 if (c==
'\\' && i+1<l)
1804 if (i>0 && !isspace((uchar)pc) &&
1805 (
isId(pc) || pc==
'*' || pc==
'&' || pc==
'.') &&
1806 (osp<8 || (osp==8 && pc!=
'-'))
1812 if (i<l-1 && (nc==
'-' || nc==
'&'))
1819 if (i>0 && !isspace((uchar)pc) &&
1820 ((i<l-1 && (
isId(nc) || nc==
'[')) ||
1821 (i<l-2 && nc==
'$' &&
isId(src[i+2])) ||
1822 (i<l-3 && nc==
'&' && src[i+2]==
'$' &&
isId(src[i+3]))
1832 if (cliSupport && i<l-1 && (
isId(nc) || nc==
'-'))
1839 if (i<l-1 && (
isId(nc) || nc==
'-'))
1845 if (i>0 && pc!=
' ' && pc!=
'\t' && pc!=
':' &&
1846 pc!=
'*' && pc!=
'&' && pc!=
'(' && pc!=
'/' &&
1847 pc!=
'.' && (osp<9 || (pc==
'>' && osp==11)))
1855 if (i>0 &&
isId(pc))
1864 if (i>0 && i<l-1 && pc!=
'=' && pc!=
':' && !isspace(pc) &&
1890 !(pc==
',' && nc==
'.'))
1899 if (c==
't' && csp==5 && i<l-1 &&
1900 !(
isId(nc) || nc==
')' || nc==
',' || isspace(nc))
1906 else if (c==
'l' && vsp==7 && i<l-1 &&
1907 !(
isId(nc) || nc==
')' || nc==
',' || isspace(nc))
1928 int templateDepth=0;
1931 if (templateDepth > 0)
1933 int nextOpenPos=name.findRev(
'>', pos);
1934 int nextClosePos=name.findRev(
'<', pos);
1935 if (nextOpenPos!=-1 && nextOpenPos>nextClosePos)
1940 else if (nextClosePos!=-1)
1952 int lastAnglePos=name.findRev(
'>', pos);
1953 int bracePos=name.findRev(
'(', pos);
1954 if (lastAnglePos!=-1 && lastAnglePos>bracePos)
1961 int bp = bracePos>0 ? name.findRev(
'(',bracePos-1) : -1;
1963 return bp==-1 || (bp>=8 && name.mid(bp-8,10)==
"operator()") ? bracePos : bp;
1972 int sl=scope.length();
1973 int nl=name.length();
1974 return (name==scope ||
1975 (scope.right(nl)==name &&
1976 sl-nl>1 && scope.at(sl-nl-1)==
':' && scope.at(sl-nl-2)==
':'
1983 int sl=scope.length();
1984 int nl=name.length();
1985 return (name==scope ||
1986 (scope.left(nl)==name &&
1987 sl>nl+1 && scope.at(nl)==
':' && scope.at(nl+1)==
':'
1995 const char *text,
bool autoBreak,
bool external,
1996 bool keepSpaces,
int indentLevel)
1999 static QRegExp regExp(
"[a-z_A-Z\\x80-\\xFF][~!a-z_A-Z0-9$\\\\.:\\x80-\\xFF]*");
2000 static QRegExp regExpSplit(
"(?!:),");
2001 QCString txtStr=text;
2002 int strLen = txtStr.length();
2011 int floatingIndex=0;
2012 if (strLen==0)
return;
2014 while ((newIndex=regExp.match(txtStr,index,&matchLen))!=-1 &&
2015 (newIndex==0 || !(txtStr.at(newIndex-1)>=
'0' && txtStr.at(newIndex-1)<=
'9'))
2019 floatingIndex+=newIndex-skipIndex+matchLen;
2020 bool insideString=FALSE;
2022 for (i=index;i<newIndex;i++)
2024 if (txtStr.at(i)==
'"') insideString=!insideString;
2028 if (strLen>35 && floatingIndex>30 && autoBreak)
2030 QCString splitText = txtStr.mid(skipIndex,newIndex-skipIndex);
2031 int splitLength = splitText.length();
2033 i=splitText.find(regExpSplit,0);
2034 if (i==-1) { i=splitText.find(
'<');
if (i!=-1) offset=0; }
2035 if (i==-1) i=splitText.find(
'>');
2036 if (i==-1) i=splitText.find(
' ');
2040 out.
writeString(splitText.left(i+offset),keepSpaces);
2041 out.
writeBreak(indentLevel==0 ? 0 : indentLevel+1);
2042 out.
writeString(splitText.right(splitLength-i-offset),keepSpaces);
2043 floatingIndex=splitLength-i-offset+matchLen;
2053 out.
writeString(txtStr.mid(skipIndex,newIndex-skipIndex),keepSpaces);
2056 QCString word=txtStr.mid(newIndex,matchLen);
2087 if (!found && (cd || (cd=
getClass(matchWord))))
2100 else if ((cd=
getClass(matchWord+
"-p")))
2129 int m = matchWord.findRev(
"::");
2137 scopeName=scope->
name();
2141 scopeName = matchWord.left(m);
2142 matchWord = matchWord.mid(m+2);
2148 getDefs(scopeName,matchWord,0,md,cd,fd,nd,gd) &&
2158 if (md!=
self && (
self==0 || md->
name()!=
self->name()))
2175 skipIndex=index=newIndex+matchLen;
2179 out.
writeString(txtStr.right(txtStr.length()-skipIndex),keepSpaces);
2190 QRegExp marker(
"@[0-9]+");
2191 int index=0,newIndex,matchLen;
2193 while ((newIndex=marker.match(exampleLine,index,&matchLen))!=-1)
2196 ol.
parseText(exampleLine.mid(index,newIndex-index));
2197 uint entryIndex = exampleLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
2221 index=newIndex+matchLen;
2223 ol.
parseText(exampleLine.right(exampleLine.length()-index));
2231 if (al==0)
return result;
2237 QCString type1 = useCanonicalType && !a->
canType.isEmpty() ?
2240 int i=type1.find(
")(");
2244 type1=type1.left(i);
2246 if (!a->
attrib.isEmpty())
2250 if (!a->
name.isEmpty() || !a->
array.isEmpty())
2252 result+= type1+
" "+a->
name+type2+a->
array;
2256 result+= type1+type2;
2258 if (!a->
defval.isEmpty() && showDefVals)
2264 if (a) result+=
", ";
2277 if (al==0)
return result;
2283 if (!a->
name.isEmpty())
2285 if (a->
type.left(4)==
"out")
2289 else if (a->
type.left(3)==
"in")
2295 result+=a->
type+
" ";
2301 int i=a->
type.length()-1;
2302 while (i>=0 &&
isId(a->
type.at(i))) i--;
2305 result+=a->
type.right(a->
type.length()-i-1);
2306 if (a->
type.find(
"...")!=-1)
2318 result+=
" extends ";
2323 if (a) result+=
", ";
2337 for (;(md=mli.current());++mli)
2373 if (src<len && buf[src] ==
'\n')
2376 else if ( c ==
'\0' && src<len-1)
2389 QStrListIterator sli(filterList);
2391 for (sli.toFirst(); (filterStr = sli.current()); ++sli)
2393 QCString fs = filterStr;
2394 int i_equals=fs.find(
'=');
2397 QCString filterPattern = fs.left(i_equals);
2399 if (fpat.match(name)!=-1)
2402 QCString filterName = fs.mid(i_equals+1);
2403 if (filterName.find(
' ')!=-1)
2405 filterName=
"\""+filterName+
"\"";
2425 if (name==0)
return "";
2427 QStrList& filterSrcList =
Config_getList(FILTER_SOURCE_PATTERNS);
2430 QCString filterName;
2432 if (isSourceCode && !filterSrcList.isEmpty())
2436 if (!found && filterName.isEmpty())
2447 if ((filterName.right(1) ==
"\"") && (filterName.left(1) ==
"\""))
2449 filterName.remove(filterName.length() - 1, 1);
2450 filterName.remove(0, 1);
2461 const char *outputEncoding =
"UTF-8";
2462 if (inputEncoding.isEmpty() || qstricmp(inputEncoding,outputEncoding)==0)
return input;
2463 int inputSize=input.length();
2464 int outputSize=inputSize*4+1;
2465 QCString output(outputSize);
2467 if (cd==(
void *)(-1))
2469 err(
"unsupported character conversion: '%s'->'%s'\n",
2470 inputEncoding.data(),outputEncoding);
2475 size_t iLeft=inputSize;
2476 size_t oLeft=outputSize;
2477 char *inputPtr = input.rawData();
2478 char *outputPtr = output.rawData();
2481 outputSize-=(int)oLeft;
2482 output.resize(outputSize+1);
2483 output.at(outputSize)=
'\0';
2488 err(
"failed to translate characters from %s to %s: check INPUT_ENCODING\ninput=[%s]\n",
2489 inputEncoding.data(),outputEncoding,input.data());
2494 return error ? input : output;
2503 if (name==0 || name[0]==0)
return 0;
2506 bool fileOpened=FALSE;
2507 if (name[0]==
'-' && name[1]==0)
2509 fileOpened=f.open(IO_ReadOnly,stdin);
2512 const int bSize=4096;
2513 QCString contents(bSize);
2516 while ((size=f.readBlock(contents.rawData()+totalSize,bSize))==bSize)
2519 contents.resize(totalSize+bSize);
2521 totalSize =
filterCRLF(contents.rawData(),totalSize+size)+2;
2522 contents.resize(totalSize);
2523 contents.at(totalSize-2)=
'\n';
2524 contents.at(totalSize-1)=
'\0';
2531 if (!fi.exists() || !fi.isFile())
2533 err(
"file `%s' not found\n",name);
2541 if (s>1 && buf.at(s-2)!=
'\n')
2551 err(
"cannot open file `%s' for reading\n",name);
2558 QDateTime current = QDateTime::currentDateTime();
2560 if (!sourceDateEpoch.isEmpty())
2563 uint64 epoch = sourceDateEpoch.toUInt64(&ok);
2566 static bool warnedOnce=FALSE;
2569 warn_uncond(
"Environment variable SOURCE_DATE_EPOCH does not contain a valid number; value is '%s'\n",
2570 sourceDateEpoch.data());
2574 else if (epoch>UINT_MAX)
2576 static bool warnedOnce=FALSE;
2579 warn_uncond(
"Environment variable SOURCE_DATA_EPOCH must have a value smaller than or equal to %llu; actual value %llu\n",UINT_MAX,epoch);
2585 current.setTimeUtc_t((ulong)epoch);
2589 current.date().month(),
2590 current.date().day(),
2591 current.date().dayOfWeek(),
2592 current.time().hour(),
2593 current.time().minute(),
2594 current.time().second(),
2600 const QDate &d=QDate::currentDate();
2602 result.sprintf(
"%d", d.year());
2617 if (cd==bcd)
return level;
2621 "inheritance relation!\n",cd->
name().data());
2629 for (;(bcdi=bcli.current());++bcli)
2652 err(
"Internal inconsistency: found class %s seem to have a recursive "
2653 "inheritance relation! Please send a bug report to dimitri@stack.nl\n",cd->
name().data());
2659 for (;(bcdi=bcli.current()) && prot!=
Private;++bcli)
2687 const QCString &namespaceName,
2688 const QCString &className,
2693 QCString scopeName=
mergeScopes(namespaceName,className);
2695 if (cd==0)
return s;
2699 int i=className.length()-1;
2700 if (i>=0 && className.at(i)==
'>')
2707 char c=className.at(i);
2708 if (c==
'>') count++,i--;
2709 else if (c==
'<') { count--;
if (count==0)
break; }
2712 QCString unspecClassName=className.left(i);
2715 while ((i=result.find(unspecClassName,p))!=-1)
2717 if (result.at(i+l)!=
'<')
2719 result=result.left(i)+className+result.right(result.length()-i-l);
2731 if (!qualName.isEmpty())
2738 QCString qualNamePart = qualName.right(qualName.length()-is);
2740 while ((i=result.find(qualNamePart,p))!=-1)
2742 int ql=qualNamePart.length();
2743 result=result.left(i)+cd->
name()+result.right(result.length()-i-ql);
2744 p=i+cd->
name().length();
2751 return result.stripWhiteSpace();
2765 int pl=pattern.length();
2772 while (p<sl && pp<pl)
2781 if (s.at(p)==
'<') bc++;
2782 else if (s.at(p)==
'>')
2795 else if (s.at(p)==pattern.at(pp))
2817 static QCString
trimScope(
const QCString &name,
const QCString &s)
2819 int scopeOffset=name.length();
2824 QCString scope=name.left(scopeOffset)+
"::";
2830 tmp+=result.mid(p,i-p);
2833 tmp+=result.right(result.length()-p);
2835 scopeOffset=name.findRev(
"::",scopeOffset-1);
2837 }
while (scopeOffset>0);
2848 for (;(bcd=bcli.current());++bcli)
2852 int spos=s.find(cd->
name()+
"::");
2855 s = s.left(spos)+s.right(
2856 s.length()-spos-cd->
name().length()-2
2870 static void trimNamespaceScope(QCString &t1,QCString &t2,
const QCString &nsName)
2876 int i1=p1==0 ? -1 : t1.findRev(
"::",p1);
2877 int i2=p2==0 ? -1 : t2.findRev(
"::",p2);
2878 if (i1==-1 && i2==-1)
2882 if (i1!=-1 && i2==-1)
2884 QCString scope=t1.left(i1);
2887 int so=nsName.length();
2890 QCString fullScope=nsName.left(so);
2891 if (!fullScope.isEmpty() && !scope.isEmpty()) fullScope+=
"::";
2895 t1 = t1.right(t1.length()-i1-2);
2902 else if ((so=nsName.findRev(
"::",so-1))==-1)
2909 else if (i1==-1 && i2!=-1)
2911 QCString scope=t2.left(i2);
2914 int so=nsName.length();
2917 QCString fullScope=nsName.left(so);
2918 if (!fullScope.isEmpty() && !scope.isEmpty()) fullScope+=
"::";
2922 t2 = t2.right(t2.length()-i2-2);
2929 else if ((so=nsName.findRev(
"::",so-1))==-1)
2944 if (target==str) { target.resize(0);
return; }
2948 while ((i=target.find(str,p))!=-1)
2950 bool isMatch = (i==0 || !
isId(target.at(i-1))) &&
2951 (i+l==(int)target.length() || !
isId(target.at(i+l)));
2954 int i1=target.find(
'*',i+l);
2955 int i2=target.find(
'&',i+l);
2956 if (i1==-1 && i2==-1)
2959 target=target.left(i)+target.right(target.length()-i-l);
2963 else if ((i1!=-1 && i<i1) || (i2!=-1 && i<i2))
2966 target=str+
" "+target.left(i)+target.right(target.length()-i-l);
2973 if (changed) target=target.stripWhiteSpace();
3011 const QCString &className,
3012 const QCString &namespaceName,
3029 QCString srcAName=srcA->
name.stripWhiteSpace();
3030 QCString dstAName=dstA->
name.stripWhiteSpace();
3031 srcAType.stripPrefix(
"class ");
3032 dstAType.stripPrefix(
"class ");
3038 if ((srcAType==
"const" || srcAType==
"volatile") && !srcAName.isEmpty())
3043 if ((dstAType==
"const" || dstAType==
"volatile") && !dstAName.isEmpty())
3048 if (srcAName==
"const" || srcAName==
"volatile")
3053 else if (dstA->
name==
"const" || dstA->
name==
"volatile")
3055 dstAType+=dstA->
name;
3063 if (qstrncmp(srcAType,
"typename ",9)==0)
3065 srcAType = srcAType.right(srcAType.length()-9);
3067 if (qstrncmp(dstAType,
"typename ",9)==0)
3069 dstAType = dstAType.right(dstAType.length()-9);
3086 if (srcAType!=dstAType)
3099 if (!className.isEmpty())
3105 if (!namespaceName.isEmpty())
3106 cd=
getClass(namespaceName+
"::"+className);
3116 if (!namespaceName.isEmpty())
3118 srcAType=
trimScope(namespaceName,srcAType);
3119 dstAType=
trimScope(namespaceName,dstAType);
3122 if (usingNamespaces && usingNamespaces->
count()>0)
3126 for (;(nd=nli.current());++nli)
3133 if (usingClasses && usingClasses->
count()>0)
3137 for (;(cd=cli.current());++cli)
3147 if (!srcAName.isEmpty() && !dstA->
type.isEmpty() &&
3148 (srcAType+
" "+srcAName)==dstAType)
3153 else if (!dstAName.isEmpty() && !srcA->
type.isEmpty() &&
3154 (dstAType+
" "+dstAName)==srcAType)
3161 uint srcPos=0,dstPos=0;
3163 while (srcPos<srcAType.length() && dstPos<dstAType.length() && equal)
3165 equal=srcAType.at(srcPos)==dstAType.at(dstPos);
3166 if (equal) srcPos++,dstPos++;
3168 uint srcATypeLen=srcAType.length();
3169 uint dstATypeLen=dstAType.length();
3170 if (srcPos<srcATypeLen && dstPos<dstATypeLen)
3174 if (srcPos==0 || dstPos==0)
3179 if (
isId(srcAType.at(srcPos)) &&
isId(dstAType.at(dstPos)))
3183 if (!srcAName.isEmpty() || !dstAName.isEmpty())
3189 while (srcPos<srcATypeLen &&
isId(srcAType.at(srcPos))) srcPos++;
3190 while (dstPos<dstATypeLen &&
isId(dstAType.at(dstPos))) dstPos++;
3191 if (srcPos<srcATypeLen ||
3192 dstPos<dstATypeLen ||
3193 (srcPos==srcATypeLen && dstPos==dstATypeLen)
3203 while (srcPos<srcATypeLen &&
isId(srcAType.at(srcPos))) srcPos++;
3204 while (dstPos<dstATypeLen &&
isId(dstAType.at(dstPos))) dstPos++;
3211 if (srcPos!=srcATypeLen || dstPos!=dstATypeLen)
3218 else if (dstPos<dstAType.length())
3220 if (!isspace((uchar)dstAType.at(dstPos)))
3222 if (!dstAName.isEmpty())
3227 while (dstPos<dstAType.length() &&
isId(dstAType.at(dstPos))) dstPos++;
3228 if (dstPos!=dstAType.length())
3237 while (dstPos<dstAType.length() &&
isId(dstAType.at(dstPos))) dstPos++;
3238 if (dstPos!=dstAType.length() || !srcAName.isEmpty())
3245 else if (srcPos<srcAType.length())
3247 if (!isspace((uchar)srcAType.at(srcPos)))
3249 if (!srcAName.isEmpty())
3254 while (srcPos<srcAType.length() &&
isId(srcAType.at(srcPos))) srcPos++;
3255 if (srcPos!=srcAType.length())
3264 while (srcPos<srcAType.length() &&
isId(srcAType.at(srcPos))) srcPos++;
3265 if (srcPos!=srcAType.length() || !dstAName.isEmpty())
3286 const char *cl,
const char *ns,
bool checkCV,
3290 QCString className=cl;
3291 QCString namespaceName=ns;
3308 if (srcAl==0 || dstAl==0)
3310 bool match = srcAl==dstAl;
3324 if ( srcAl->count()==0 && dstAl->count()==1 &&
3325 dstAl->getFirst()->type==
"void" )
3333 if ( dstAl->count()==0 && srcAl->count()==1 &&
3334 srcAl->getFirst()->type==
"void" )
3343 if (srcAl->count() != dstAl->count())
3367 for (;(srcA=srcAli.current()) && (dstA=dstAli.current());++srcAli,++dstAli)
3370 usingNamespaces,usingClasses))
3383 static QCString resolveSymbolName(
FileDef *fs,
Definition *symbol,QCString &templSpec)
3407 int i=s.find(
" class ");
3408 if (i!=-1)
return s.left(i)+s.mid(i+6);
3409 i=s.find(
" typename ");
3410 if (i!=-1)
return s.left(i)+s.mid(i+9);
3411 i=s.find(
" union ");
3412 if (i!=-1)
return s.left(i)+s.mid(i+6);
3413 i=s.find(
" struct ");
3414 if (i!=-1)
return s.left(i)+s.mid(i+7);
3424 QCString templSpec = spec.stripWhiteSpace();
3427 if (!templSpec.isEmpty() && templSpec.at(0) ==
'<')
3429 templSpec =
"< " +
extractCanonicalType(d,fs,templSpec.right(templSpec.length()-1).stripWhiteSpace());
3432 if (!resolvedType.isEmpty())
3434 templSpec = resolvedType;
3443 QCString *tSpec,
int count=0)
3445 if (count>10)
return word;
3447 QCString symName,result,templSpec,tmpName;
3449 if (tSpec && !tSpec->isEmpty())
3452 if (word.findRev(
"::")!=-1 && !(tmpName=
stripScope(word)).isEmpty())
3466 QCString resolvedType;
3469 cd =
getResolvedClass(d,fs,word+templSpec,&mType,&ts,TRUE,TRUE,&resolvedType);
3470 bool isTemplInst = cd && !templSpec.isEmpty();
3471 if (!cd && !templSpec.isEmpty())
3500 if (cd==d && tSpec) *tSpec=
"";
3504 result = resolvedType+ts;
3512 if (tSpec) *tSpec=
"";
3514 else if (!ts.isEmpty() && templSpec.isEmpty())
3524 if (!templSpec.isEmpty())
3526 result=cd->
name()+templSpec;
3535 else if (ts.isEmpty() && !templSpec.isEmpty() && cd && !cd->
isTemplate() && tSpec)
3565 if (resolvedType.isEmpty())
3571 result = resolvedType;
3580 type = type.stripWhiteSpace();
3586 type.stripPrefix(
"class ");
3587 type.stripPrefix(
"struct ");
3588 type.stripPrefix(
"union ");
3589 type.stripPrefix(
"enum ");
3590 type.stripPrefix(
"typename ");
3599 QCString templSpec,word;
3605 if (i>pp) canType += type.mid(pp,i-pp);
3613 if (ct.isEmpty() && type.mid(p,2)==
"::")
3623 if (!templSpec.isEmpty())
3627 static QRegExp re(
"[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*");
3631 while ((ti=re.match(templSpec,tp,&tl))!=-1)
3633 canType += templSpec.mid(tp,ti-tp);
3637 canType+=templSpec.right(templSpec.length()-tp);
3642 canType += type.right(type.length()-pp);
3650 QCString type = arg->
type.stripWhiteSpace();
3651 QCString name = arg->
name;
3653 if ((type==
"const" || type==
"volatile") && !name.isEmpty())
3658 if (name==
"const" || name==
"volatile")
3660 if (!type.isEmpty()) type+=
" ";
3663 if (!arg->
array.isEmpty())
3687 QCString sSrcName =
" "+srcA->
name;
3688 QCString sDstName =
" "+dstA->
name;
3689 QCString srcType = srcA->
type;
3690 QCString dstType = dstA->
type;
3695 if (sSrcName==dstType.right(sSrcName.length()))
3697 srcA->
type+=sSrcName;
3701 else if (sDstName==srcType.right(sDstName.length()))
3703 dstA->
type+=sDstName;
3739 ASSERT(srcScope!=0 && dstScope!=0);
3741 if (srcAl==0 || dstAl==0)
3743 bool match = srcAl==dstAl;
3757 if ( srcAl->count()==0 && dstAl->count()==1 &&
3758 dstAl->getFirst()->type==
"void" )
3766 if ( dstAl->count()==0 && srcAl->count()==1 &&
3767 srcAl->getFirst()->type==
"void" )
3776 if (srcAl->count() != dstAl->count())
3800 for (;(srcA=srcAli.current()) && (dstA=dstAli.current());++srcAli,++dstAli)
3803 dstScope,dstFileScope,dstA)
3823 if (srcAl==0 || dstAl==0 || srcAl->count()!=dstAl->count())
3830 for (;(srcA=srcAli.current()) && (dstA=dstAli.current());++srcAli,++dstAli)
3837 else if (!srcA->
defval.isEmpty() && dstA->
defval.isEmpty())
3845 if (srcA->
name==
"const" || srcA->
name==
"volatile")
3848 srcA->
name.resize(0);
3850 if (dstA->
name==
"const" || dstA->
name==
"volatile")
3853 dstA->
name.resize(0);
3859 if (srcA->
name.isEmpty() && !dstA->
name.isEmpty())
3866 else if (!srcA->
name.isEmpty() && dstA->
name.isEmpty())
3873 else if (!srcA->
name.isEmpty() && !dstA->
name.isEmpty())
3876 if (forceNameOverwrite)
3882 if (srcA->
docs.isEmpty() && !dstA->
docs.isEmpty())
3886 else if (!srcA->
docs.isEmpty() && dstA->
docs.isEmpty())
3896 srcA->
type=srcA->
type.stripWhiteSpace();
3897 dstA->
type=dstA->
type.stripWhiteSpace();
3908 else if (srcA->
name.isEmpty() && !dstA->
name.isEmpty())
3912 else if (dstA->
name.isEmpty() && !srcA->
name.isEmpty())
3917 int i1=srcA->
type.find(
"::"),
3918 i2=dstA->
type.find(
"::"),
3919 j1=srcA->
type.length()-i1-2,
3920 j2=dstA->
type.length()-i2-2;
3921 if (i1!=-1 && i2==-1 && srcA->
type.right(j1)==dstA->
type)
3928 else if (i1==-1 && i2!=-1 && dstA->
type.right(j2)==srcA->
type)
3935 if (srcA->
docs.isEmpty() && !dstA->
docs.isEmpty())
3939 else if (dstA->
docs.isEmpty() && !srcA->
docs.isEmpty())
3954 const char *forceTagFile,
3955 QList<MemberDef> &members)
3961 for (mli.toFirst();(md=mli.current());++mli)
3971 currentFile==0 || fd==currentFile)
3976 if (args && !md->
isDefine() && qstrcmp(args,
"()")!=0)
3985 delete argList; argList=0;
3987 if (match && (forceTagFile==0 || md->
getReference()==forceTagFile))
4019 const QCString &mbName,
4026 bool forceEmptyScope,
4029 const char *forceTagFile
4032 fd=0, md=0, cd=0, nd=0, gd=0;
4033 if (mbName.isEmpty())
return FALSE;
4035 QCString scopeName=scName;
4036 QCString memberName=mbName;
4038 memberName =
substitute(memberName,
"\\",
"::");
4044 while ((is=scopeName.findRev(
"::"))!=-1 &&
4045 (im=memberName.find(
"::",pm))!=-1 &&
4046 (scopeName.right(scopeName.length()-is-2)==memberName.mid(pm,im-pm))
4049 scopeName=scopeName.left(is);
4055 QCString mName=memberName;
4057 if (memberName.left(9)!=
"operator " &&
4059 (im=memberName.findRev(
"::"))!=-1 &&
4060 im<(
int)memberName.length()-2
4063 mScope=memberName.left(im);
4064 mName=memberName.right(memberName.length()-im-2);
4068 if (mScope==scopeName) scopeName.resize(0);
4075 if ((!forceEmptyScope || scopeName.isEmpty()) &&
4076 mn && !(scopeName.isEmpty() && mScope.isEmpty()))
4079 int scopeOffset=scopeName.length();
4082 QCString className = scopeName.left(scopeOffset);
4083 if (!className.isEmpty() && !mScope.isEmpty())
4085 className+=
"::"+mScope;
4087 else if (!mScope.isEmpty())
4094 if (fcd==0 && className.find(
'<')!=-1)
4115 for (mmli.toFirst();(mmd=mmli.current());++mmli)
4120 bool match=args==0 ||
4132 if (m<mdist && mcd->isLinkable())
4144 delete argList; argList=0;
4150 for (mmli.toFirst();(mmd=mmli.current());++mmli)
4159 if (m<mdist /* && mcd->isLinkable()*/ )
4195 for (;(emd=tmi.current());++tmi)
4220 else if ((scopeOffset=scopeName.findRev(
"::",scopeOffset-1))==-1)
4224 }
while (scopeOffset>=0);
4227 if (mn && scopeName.isEmpty() && mScope.isEmpty())
4233 bool hasEmptyArgs = args && qstrcmp(args,
"()") == 0;
4238 for (mmli.toFirst(); (mmd = mmli.current()); ++mmli)
4253 if (!fuzzy_mmd && hasEmptyArgs)
4257 if (argList)
delete argList, argList = 0;
4259 mmd = mmd ? mmd : fuzzy_mmd;
4277 int scopeOffset=scopeName.length();
4280 QCString namespaceName = scopeName.left(scopeOffset);
4281 if (!namespaceName.isEmpty() && !mScope.isEmpty())
4283 namespaceName+=
"::"+mScope;
4285 else if (!mScope.isEmpty())
4287 namespaceName=mScope.copy();
4290 if (!namespaceName.isEmpty() &&
4300 for (mmli.toFirst();((mmd=mmli.current()) && !found);++mmli)
4327 if (args && qstrcmp(args,
"()")!=0)
4345 delete argList; argList=0;
4349 if (!found && args && !qstrcmp(args,
"()"))
4353 for (mmli.toFirst();((mmd=mmli.current()) && !found);++mmli)
4384 for (mmli.toFirst();(mmd=mmli.current());++mmli)
4388 int ni=namespaceName.findRev(
"::");
4390 bool notInNS = tmd && ni==-1 && tmd->
getNamespaceDef()==0 && (mScope.isEmpty() || mScope==tmd->
name());
4394 (notInNS || sameNS) &&
4395 namespaceName.length()>0
4412 else if ((scopeOffset=scopeName.findRev(
"::",scopeOffset-1))==-1)
4416 }
while (scopeOffset>=0);
4420 QList<MemberDef> members;
4423 if (members.count()==0)
4429 if (members.count()!=1 && args && !qstrcmp(args,
"()"))
4434 for (mni.toLast();(md=mni.current());--mni)
4451 if (members.count()>0)
4456 QListIterator<MemberDef> mit(members);
4457 for (mit.toFirst();(md=mit.current());++mit)
4466 md=members.getLast();
4471 md=members.getLast();
4509 QCString scopeName=scope;
4511 if (scopeName.isEmpty())
return FALSE;
4513 bool explicitGlobalScope=FALSE;
4514 if (scopeName.at(0)==
':' && scopeName.at(1)==
':')
4516 scopeName=scopeName.right(scopeName.length()-2);
4517 explicitGlobalScope=TRUE;
4520 QCString docScopeName=docScope;
4521 int scopeOffset=explicitGlobalScope ? 0 : docScopeName.length();
4525 QCString fullName=scopeName.copy();
4526 if (scopeOffset>0) fullName.prepend(docScopeName.left(scopeOffset)+
"::");
4543 else if ((scopeOffset=docScopeName.findRev(
"::",scopeOffset-1))==-1)
4547 }
while (scopeOffset>=0);
4554 uchar *p=(uchar*)s.data();
4555 if (p==0)
return TRUE;
4557 while ((c=*p++))
if (!islower(c))
return FALSE;
4569 bool lookForSpecialization,
4575 QCString tsName = name;
4577 QCString fullName =
substitute(tsName,
"#",
"::");
4578 if (fullName.find(
"anonymous_namespace{")==-1)
4588 int endNamePos=bracePos!=-1 ? bracePos : fullName.length();
4589 int scopePos=fullName.findRev(
"::",endNamePos);
4590 bool explicitScope = fullName.left(2)==
"::" &&
4592 tsName.left(2)==
"::" ||
4607 if (!inSeeBlock && scopePos==-1 &&
isLowerCase(tsName))
4615 if (scName!=fullName &&
getScopeDefs(scName,fullName,cd,nd))
4628 else if (scName==fullName || (!inSeeBlock && scopePos==-1))
4640 QCString nameStr=fullName.left(endNamePos);
4641 if (explicitScope) nameStr=nameStr.mid(2);
4645 if (bracePos!=-1) argsStr=fullName.right(fullName.length()-bracePos);
4649 int templPos=nameStr.find(
'<');
4650 bool tryUnspecializedVersion = FALSE;
4651 if (templPos!=-1 && nameStr.find(
"operator")==-1)
4653 int endTemplPos=nameStr.findRev(
'>');
4654 if (endTemplPos!=-1)
4656 if (!lookForSpecialization)
4658 nameStr=nameStr.left(templPos)+nameStr.right(nameStr.length()-endTemplPos-1);
4662 tryUnspecializedVersion = TRUE;
4667 QCString scopeStr=scName;
4678 if (
getDefs(scopeStr,nameStr,argsStr,
4690 (!scopeStr.isEmpty() || nameStr.find(
"::")>0))
4701 if (md) { *resMember=md; *resContext=md; }
4702 else if (cd) *resContext=cd;
4703 else if (nd) *resContext=nd;
4704 else if (fd) *resContext=fd;
4705 else if (gd) *resContext=gd;
4706 else { *resContext=0; *resMember=0;
return FALSE; }
4716 else if (tsName.find(
'.')!=-1)
4727 if (tryUnspecializedVersion)
4729 return resolveRef(scName,name,inSeeBlock,resContext,resMember,FALSE,0,checkScope);
4733 *resContext=
getClass(fullName.left(bracePos));
4747 QCString result=link;
4748 if (!result.isEmpty())
4753 if (!isFileName && result.find(
'<')==-1) result=
substitute(result,
".",
"::");
4755 if (result.at(0)==
':' && result.at(1)==
':')
4757 result=result.right(result.length()-2);
4789 const char *name,
bool inSeeBlock,
const char *rt)
4799 if (
resolveRef(scName,name,inSeeBlock,&compound,&md))
4817 linkText=((
GroupDef *)compound)->groupTitle();
4847 QCString linkRef=lr;
4858 if (linkRef.isEmpty())
4869 if (si) resAnchor = si->
label;
4880 resAnchor = si->
label;
4905 else if ((cd=
getClass(linkRefWithoutTemplates)))
4911 else if ((cd=
getClass(linkRef+
"-p")))
4937 bool res =
resolveRef(scName,lr,TRUE,resContext,&md);
4938 if (md) resAnchor=md->
anchor();
4952 const char *lr,
bool inSeeBlock,
const char *lt)
4959 if (
resolveLink(clName,lr,inSeeBlock,&compound,anchor))
4963 if (lt==0 && anchor.isEmpty() &&
4967 linkText=((
GroupDef *)compound)->groupTitle();
4982 err(
"%s:%d: Internal error: resolveLink successful but no compound found!",__FILE__,__LINE__);
4996 QCString linkText = text ? text : name;
5015 if (s.isEmpty())
return result;
5016 QRegExp r(
"[a-z_A-Z][a-z_A-Z0-9]*");
5017 while ((p=r.match(s,i,&l))!=-1)
5020 if (p>i) result+=s.mid(i,p-i);
5021 if ((subst=substituteDict[s.mid(p,l)]))
5031 result+=s.mid(i,s.length()-i);
5053 const int maxAddrSize = 20;
5054 char addr[maxAddrSize];
5055 qsnprintf(addr,maxAddrSize,
"%p:",fnDict);
5056 QCString key = addr;
5064 ambig = cachedResult->
isAmbig;
5073 QCString name=QDir::cleanDirPath(n).utf8();
5077 if (name.isEmpty())
goto exit;
5078 slashPos=QMAX(name.findRev(
'/'),name.findRev(
'\\'));
5081 path=name.left(slashPos+1);
5082 name=name.right(name.length()-slashPos-1);
5085 if (name.isEmpty())
goto exit;
5086 if ((fn=(*fnDict)[name]))
5092 #if defined(_WIN32) || defined(__MACOSX__) // Windows or MacOSX
5093 bool isSamePath = fd->
getPath().right(path.length()).lower()==path.lower();
5095 bool isSamePath = fd->
getPath().right(path.length())==path;
5097 if (path.isEmpty() || isSamePath)
5112 for (fni.toFirst();(fd=fni.current());++fni)
5115 if (path.isEmpty() || fdStripPath.right(pathStripped.length())==pathStripped)
5124 cachedResult->
isAmbig = ambig;
5125 cachedResult->
fileDef = lastMatch;
5148 int slashPos=QMAX(name.findRev(
'/'),name.findRev(
'\\'));
5151 path=name.left(slashPos+1);
5152 name=name.right(name.length()-slashPos-1);
5155 if ((fn=(*fnDict)[name]))
5159 for (fni.toFirst();(fd=fni.current());++fni)
5161 if (path.isEmpty() || fd->
getPath().right(path.length())==path)
5173 QCString
substitute(
const QCString &s,
const QCString &src,
const QCString &dst)
5175 if (s.isEmpty() || src.isEmpty())
return s;
5177 int srcLen = src.length();
5178 int dstLen = dst.length();
5183 for (count=0, p=s.data(); (q=strstr(p,src))!=0; p=q+srcLen) count++;
5184 resLen = s.length()+count*(dstLen-srcLen);
5188 resLen = s.length();
5190 QCString result(resLen+1);
5192 for (r=result.rawData(), p=s; (q=strstr(p,src))!=0; p=q+srcLen)
5197 if (dst) memcpy(r,dst,dstLen);
5208 const char *projName,
const char *projNum,
const char *projBrief)
5210 QCString result = s;
5211 if (title) result =
substitute(result,
"$title",title);
5216 result =
substitute(result,
"$projectname",projName);
5217 result =
substitute(result,
"$projectnumber",projNum);
5218 result =
substitute(result,
"$projectbrief",projBrief);
5231 if (name.isEmpty())
return 0;
5233 char *s = sl.first();
5237 const char *pd=name.data();
5239 while (*ps!=0 && *pd!=0 && *ps==*pd) ps++,pd++,i++;
5240 if (*ps==0 && *pd!=0)
5255 for ( ; bcli.current(); ++bcli)
5257 ClassDef *cd=bcli.current()->classDef;
5283 for ( ; bcli.current() ; ++bcli)
5285 if (bcli.current()->classDef->isVisibleInHierarchy())
5300 for ( ; (cd=cli.current()); ++cli)
5314 for ( ; bcli.current(); ++bcli)
5316 ClassDef *cd=bcli.current()->classDef;
5330 static bool allowUnicodeNames =
Config_getBool(ALLOW_UNICODE_NAMES);
5339 case '_':
if (allowUnderscore) growBuf.
addChar(
'_');
else growBuf.
addStr(
"__");
break;
5340 case '-': growBuf.
addChar(
'-');
break;
5341 case ':': growBuf.
addStr(
"_1");
break;
5342 case '/': growBuf.
addStr(
"_2");
break;
5343 case '<': growBuf.
addStr(
"_3");
break;
5344 case '>': growBuf.
addStr(
"_4");
break;
5345 case '*': growBuf.
addStr(
"_5");
break;
5346 case '&': growBuf.
addStr(
"_6");
break;
5347 case '|': growBuf.
addStr(
"_7");
break;
5348 case '.':
if (allowDots) growBuf.
addChar(
'.');
else growBuf.
addStr(
"_8");
break;
5349 case '!': growBuf.
addStr(
"_9");
break;
5350 case ',': growBuf.
addStr(
"_00");
break;
5351 case ' ': growBuf.
addStr(
"_01");
break;
5352 case '{': growBuf.
addStr(
"_02");
break;
5353 case '}': growBuf.
addStr(
"_03");
break;
5354 case '?': growBuf.
addStr(
"_04");
break;
5355 case '^': growBuf.
addStr(
"_05");
break;
5356 case '%': growBuf.
addStr(
"_06");
break;
5357 case '(': growBuf.
addStr(
"_07");
break;
5358 case ')': growBuf.
addStr(
"_08");
break;
5359 case '+': growBuf.
addStr(
"_09");
break;
5360 case '=': growBuf.
addStr(
"_0A");
break;
5361 case '$': growBuf.
addStr(
"_0B");
break;
5362 case '\\': growBuf.
addStr(
"_0C");
break;
5363 case '@': growBuf.
addStr(
"_0D");
break;
5368 const unsigned char uc = (
unsigned char)c;
5369 bool doEscape = TRUE;
5370 if (allowUnicodeNames && uc <= 0xf7)
5375 if ((uc&0xE0)==0xC0)
5379 if ((uc&0xF0)==0xE0)
5383 if ((uc&0xF8)==0xF0)
5388 for (
int m=1; m<l && !doEscape; ++m)
5390 unsigned char ct = (
unsigned char)*pt;
5391 if (ct==0 || (ct&0xC0)!=0x80)
5409 static char map[] =
"0123456789ABCDEF";
5410 unsigned char id = (
unsigned char)c;
5419 else if (caseSenseNames || !isupper(c))
5432 return growBuf.
get();
5441 if (name==0 || name[0]==
'\0')
return "";
5447 static QDict<int> usedNames(10007);
5448 usedNames.setAutoDelete(TRUE);
5451 int *value=usedNames.find(name);
5455 usedNames.insert(name,
new int(count));
5462 result.sprintf(
"a%05d",num);
5467 int resultLen = result.length();
5472 QCString sigStr(33);
5473 MD5Buffer((
const unsigned char *)result.data(),resultLen,md5_sig);
5474 MD5SigToString(md5_sig,sigStr.rawData(),33);
5475 result=result.left(128-32)+sigStr;
5480 int l1Dir=0,l2Dir=0;
5482 #if MAP_ALGO==ALGO_COUNT
5490 static int curDirNum=0;
5495 l1Dir = (curDirNum)&0xf;
5496 l2Dir = (curDirNum>>4)&0xff;
5501 l1Dir = (*dirNum)&0xf;
5502 l2Dir = ((*dirNum)>>4)&0xff;
5504 #elif MAP_ALGO==ALGO_CRC16
5506 int dirNum = qChecksum(result,result.length());
5508 l2Dir = (dirNum>>4)&0xff;
5509 #elif MAP_ALGO==ALGO_MD5
5512 MD5Buffer((
const unsigned char *)result.data(),result.length(),md5_sig);
5513 l1Dir = md5_sig[14]&0xf;
5514 l2Dir = md5_sig[15];
5516 result.prepend(QCString().sprintf(
"d%x/d%02x/",l1Dir,l2Dir));
5534 int i = n.findRev(
'/');
5550 for (l1=0;l1<16;l1++)
5552 d.mkdir(QCString().sprintf(
"d%x",l1));
5553 for (l2=0;l2<256;l2++)
5555 d.mkdir(QCString().sprintf(
"d%x/d%02x",l1,l2));
5565 QCString &className,QCString &namespaceName,
5566 bool allowEmptyClass)
5569 QCString clName=scopeName;
5573 namespaceName=nd->
name().copy();
5574 className.resize(0);
5577 p=clName.length()-2;
5578 while (p>=0 && (i=clName.findRev(
"::",p))!=-1)
5585 namespaceName=nd->
name().copy();
5586 className=clName.right(clName.length()-i-2);
5594 className=scopeName.copy();
5595 namespaceName.resize(0);
5598 if (className.isEmpty() && !namespaceName.isEmpty() && !allowEmptyClass)
5601 className=namespaceName.copy();
5602 namespaceName.resize(0);
5606 if ( className.right(2)==
"-p")
5608 className = className.left(className.length()-2);
5615 QCString result=scope.copy();
5616 if (!templ.isEmpty() && scope.find(
'<')==-1)
5621 (si=scope.find(
"::",pi))!=-1 && !
getClass(scope.left(si)+templ) &&
5634 result=scope.left(si) + templ + scope.right(scope.length()-si);
5642 #if 0 // original version
5648 QCString result = name;
5649 int l=result.length();
5656 char c=result.at(p);
5661 return result.right(l-p-1);
5667 while (p>=0 && !done)
5672 case '>': count++;
break;
5673 case '<': count--;
if (count<=0) done=TRUE;
break;
5693 QCString result = name;
5694 int l=result.length();
5697 bool skipBracket=FALSE;
5703 while (p>=0 && count>=0)
5705 char c=result.at(p);
5711 if (p>0 && result.at(p-1)==
':')
return result.right(l-p-1);
5721 if (p>0 && result.at(p-1)==
'>')
5729 bool foundMatch=
false;
5730 while (p>=0 && !foundMatch)
5741 if (result.at(p-1) ==
'<')
5748 foundMatch = count==0;
5762 done = count==0 || skipBracket;
5773 static const char hex[] =
"0123456789ABCDEF";
5776 if (s==0)
return "";
5783 if ((c>=
'0' && c<=
'9') || (c>=
'a' && c<=
'z') || (c>=
'A' && c<=
'Z') || c==
'-' || c==
':' || c==
'.')
5785 if (first && c>=
'0' && c<=
'9') growBuf.
addChar(
'a');
5791 encChar[1]=hex[((
unsigned char)c)>>4];
5792 encChar[2]=hex[((
unsigned char)c)&0xF];
5799 return growBuf.
get();
5807 if (s==0)
return "";
5814 case '<': growBuf.
addStr(
"<");
break;
5815 case '>': growBuf.
addStr(
">");
break;
5816 case '&': growBuf.
addStr(
"&");
break;
5817 case '\'': growBuf.
addStr(
"'");
break;
5818 case '"': growBuf.
addStr(
""");
break;
5819 case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
5820 case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
5821 case 19:
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
case 26:
5822 case 27:
case 28:
case 29:
case 30:
case 31:
5824 default: growBuf.
addChar(c);
break;
5828 return growBuf.
get();
5836 if (s==0)
return "";
5843 case '<': growBuf.
addStr(
"<");
break;
5844 case '>': growBuf.
addStr(
">");
break;
5845 case '&':
if (keepEntities)
5851 if (ce==
';' || (!(
isId(ce) || ce==
'#')))
break;
5857 while (p<e) growBuf.
addChar(*p++);
5869 case '\'': growBuf.
addStr(
"'");
break;
5870 case '"': growBuf.
addStr(
""");
break;
5871 default: growBuf.
addChar(c);
break;
5875 return growBuf.
get();
5882 if (s==0)
return "";
5889 case '"': growBuf.
addStr(
"\\\"");
break;
5890 case '\\': growBuf.
addStr(
"\\\\");
break;
5891 default: growBuf.
addChar(c);
break;
5903 return result.data();
5911 static QRegExp entityPat(
"&[a-zA-Z]+[0-9]*;");
5913 if (s.length()==0)
return result;
5917 while ((p=entityPat.match(s,i,&l))!=-1)
5921 growBuf.
addStr(s.mid(i,p-i));
5923 QCString entity = s.mid(p,l);
5932 growBuf.
addStr(s.mid(p,l));
5936 growBuf.
addStr(s.mid(i,s.length()-i));
5939 return growBuf.
get();
5963 for (index=0;(md=mli.current());)
5972 for (fmli.toFirst();(fmd=fmli.current());++fmli)
5982 if (*ppMemberGroupSDict==0)
5987 MemberGroup *mg = (*ppMemberGroupSDict)->find(groupId);
5998 (*ppMemberGroupSDict)->append(groupId,mg);
6015 if (*ppMemberGroupSDict==0)
6020 MemberGroup *mg = (*ppMemberGroupSDict)->find(groupId);
6031 (*ppMemberGroupSDict)->append(groupId,mg);
6033 md = ml->
take(index);
6051 static const QRegExp re_norm(
"[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9:\\x80-\\xFF]*");
6052 static const QRegExp re_ftn(
"[a-z_A-Z\\x80-\\xFF][()=_a-z_A-Z0-9:\\x80-\\xFF]*");
6056 templSpec.resize(0);
6058 int typeLen=type.length();
6063 if (type.at(pos)==
',')
return -1;
6064 if (type.left(4).lower()==
"type")
6078 if ((i=re.match(type,pos,&l))!=-1)
6083 while (type.at(ts)==
' ' && ts<typeLen) ts++,tl++;
6084 if (type.at(ts)==
'<')
6089 while (te<typeLen && brCount!=0)
6091 if (type.at(te)==
'<')
6093 if (te<typeLen-1 && type.at(te+1)==
'<') te++;
else brCount++;
6095 if (type.at(te)==
'>')
6097 if (te<typeLen-1 && type.at(te+1)==
'>') te++;
else brCount--;
6102 name = type.mid(i,l);
6105 templSpec = type.mid(ts,te-ts),tl+=te-ts;
6124 const QCString &name,
6129 int p=name.find(
'<');
6130 if (p==-1)
return name;
6132 QCString result = name.left(p);
6134 static QRegExp re(
"[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*");
6137 while ((i=re.match(name,p,&l))!=-1)
6139 result += name.mid(p,i-p);
6140 QCString n = name.mid(i,l);
6146 for (formAli.toFirst();
6147 (formArg=formAli.current()) && !found;
6151 found = formArg->
name==n;
6173 result+=name.right(name.length()-p);
6186 const QCString &name,
6192 if (formalArgs==0)
return name;
6194 static QRegExp re(
"[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*");
6197 while ((i=re.match(name,p,&l))!=-1)
6199 result += name.mid(p,i-p);
6200 QCString n = name.mid(i,l);
6209 for (formAli.toFirst();
6210 (formArg=formAli.current()) && !found;
6214 actArg = actAli.current();
6215 if (formArg->
type.left(6)==
"class " && formArg->
name.isEmpty())
6217 formArg->
name = formArg->
type.mid(6);
6218 formArg->
type =
"class";
6220 if (formArg->
type.left(9)==
"typename " && formArg->
name.isEmpty())
6222 formArg->
name = formArg->
type.mid(9);
6223 formArg->
type =
"typename";
6225 if (formArg->
type==
"class" || formArg->
type==
"typename" || formArg->
type.left(8)==
"template")
6232 if (formArg->
name==n && actArg && !actArg->
type.isEmpty())
6242 if (actArg->
name.isEmpty())
6244 result += actArg->
type+
" ";
6251 result += actArg->
type+
" "+actArg->
name+
" ";
6256 else if (formArg->
name==n &&
6258 !formArg->
defval.isEmpty() &&
6266 else if (formArg->
name==n &&
6268 !formArg->
defval.isEmpty() &&
6282 result+=name.right(name.length()-p);
6285 return result.stripWhiteSpace();
6293 ASSERT(srcLists!=0);
6294 QList<ArgumentList> *dstLists =
new QList<ArgumentList>;
6295 dstLists->setAutoDelete(TRUE);
6296 QListIterator<ArgumentList> sli(*srcLists);
6298 for (;(sl=sli.current());++sli)
6314 QCString *pLastScopeStripped)
6318 int l=fullName.length();
6319 int i=fullName.find(
'<');
6326 while (e<l && !done)
6328 char c=fullName.at(e++);
6339 int si= fullName.find(
"::",e);
6341 if (parentOnly && si==-1)
break;
6344 result+=fullName.mid(p,i-p);
6346 if (
getClass(result+fullName.mid(i,e-i))!=0)
6348 result+=fullName.mid(i,e-i);
6351 else if (pLastScopeStripped)
6354 *pLastScopeStripped=fullName.mid(i,e-i);
6357 i=fullName.find(
'<',p);
6359 result+=fullName.right(l-p);
6373 QCString
mergeScopes(
const QCString &leftScope,
const QCString &rightScope)
6378 int i=0,p=leftScope.length();
6383 while ((i=leftScope.findRev(
"::",p))!=-1)
6385 if (
leftScopeMatch(rightScope,leftScope.right(leftScope.length()-i-2)))
6387 result = leftScope.left(i+2)+rightScope;
6392 if (found)
return result;
6395 result=leftScope.copy();
6396 if (!result.isEmpty() && !rightScope.isEmpty()) result+=
"::";
6414 if (sp>=sl)
return -1;
6418 if (c==
':') sp++,p++;
else break;
6430 while (sp<sl && !done)
6436 case '<': count++;
break;
6437 case '>': count--;
if (count==0) done=TRUE;
break;
6456 const QCString &
doc,
6457 QList<SectionInfo> * ,
6458 const char *fileName,
int startLine,
6459 const QList<ListItemInfo> *sli,
6475 QCString baseName=name;
6476 if (baseName.right(4)==
".tex")
6477 baseName=baseName.left(baseName.length()-4);
6481 QCString title=ptitle.stripWhiteSpace();
6482 pd=
new PageDef(fileName,startLine,baseName,doc,title);
6498 if (!pd->
title().isEmpty())
6517 warn(file,-1,
"multiple use of section label '%s', (first occurrence: %s, line %d)",pd->
name().data(),si->
fileName.data(),si->
lineNr);
6521 warn(file,-1,
"multiple use of section label '%s', (first occurrence: %s)",pd->
name().data(),si->
fileName.data());
6544 const char *prefix,
const char *name,
const char *title,
const char *args,
Definition *scope)
6547 if (sli && key && key[0]!=
'@')
6549 QListIterator<ListItemInfo> slii(*sli);
6551 for (slii.toFirst();(lii=slii.current());++slii)
6569 item->
scope = scope;
6571 item->
title = title;
6595 for (gli.toFirst();(gd=gli.current());++gli)
6601 if (!first) { ol.
writeString(
" | "); }
else first=FALSE;
6620 bool insideTabbing,
bool insidePre,
bool insideItem,
bool keepSpaces)
6624 const unsigned char *p=(
const unsigned char *)str;
6625 const unsigned char *q;
6628 unsigned char pc=
'\0';
6637 case '\\': t <<
"\\(\\backslash\\)";
break;
6638 case '{': t <<
"\\{";
break;
6639 case '}': t <<
"\\}";
break;
6640 case '_': t <<
"\\_";
break;
6641 case ' ':
if (keepSpaces) t <<
"~";
else t <<
' ';
6652 case '#': t <<
"\\#";
break;
6653 case '$': t <<
"\\$";
break;
6654 case '%': t <<
"\\%";
break;
6655 case '^': t <<
"$^\\wedge$";
break;
6659 while ((*q >=
'a' && *q <=
'z') || (*q >=
'A' && *q <= 'Z') || (*q >=
'0' && *q <=
'9'))
6685 case '*': t <<
"$\\ast$";
break;
6686 case '_':
if (!insideTabbing) t <<
"\\+";
6688 if (!insideTabbing) t <<
"\\+";
6690 case '{': t <<
"\\{";
break;
6691 case '}': t <<
"\\}";
break;
6692 case '<': t <<
"$<$";
break;
6693 case '>': t <<
"$>$";
break;
6694 case '|': t <<
"$\\vert$";
break;
6695 case '~': t <<
"$\\sim$";
break;
6701 case ']':
if (pc==
'[') t <<
"$\\,$";
6707 case '-': t <<
"-\\/";
6709 case '\\': t <<
"\\textbackslash{}";
6711 case '"': t <<
"\\char`\\\"{}";
6713 case '\'': t <<
"\\textquotesingle{}";
6715 case ' ':
if (keepSpaces) {
if (insideTabbing) t <<
"\\>";
else t <<
'~'; }
else t <<
' ';
6720 if (!insideTabbing &&
6721 ((c>=
'A' && c<=
'Z' && pc!=
' ' && pc!=
'\0' && *p) || (c==
':' && pc!=
':') || (pc==
'.' &&
isId(c)))
6736 QCString
tmp(qstrlen(s)+1);
6745 case '|': t <<
"\\texttt{\"|}";
break;
6746 case '!': t <<
"\"!";
break;
6747 case '%': t <<
"\\%";
break;
6748 case '{': t <<
"\\lcurly{}";
break;
6749 case '}': t <<
"\\rcurly{}";
break;
6750 case '~': t <<
"````~";
break;
6756 while ((c=*p) && c!=
'|' && c!=
'!' && c!=
'%' && c!=
'{' && c!=
'}' && c!=
'~')
6766 return result.data();
6772 QCString
tmp(qstrlen(s)+1);
6781 case '!': t <<
"\"!";
break;
6782 case '"': t <<
"\"\"";
break;
6783 case '@': t <<
"\"@";
break;
6784 case '|': t <<
"\\texttt{\"|}";
break;
6785 case '[': t <<
"[";
break;
6786 case ']': t <<
"]";
break;
6787 case '{': t <<
"\\lcurly{}";
break;
6788 case '}': t <<
"\\rcurly{}";
break;
6794 while ((c=*p) && c!=
'"' && c!=
'@' && c!=
'[' && c!=
']' && c!=
'!' && c!=
'{' && c!=
'}' && c!=
'|')
6804 return result.data();
6817 case '\\': t <<
"\\textbackslash{}";
break;
6818 case '{': t <<
"\\{";
break;
6819 case '}': t <<
"\\}";
break;
6820 case '_': t <<
"\\_";
break;
6821 case '%': t <<
"\\%";
break;
6822 case '&': t <<
"\\&";
break;
6828 return result.data();
6834 static QCString g_nextTag(
"AAAAAAAAAA" );
6835 static QDict<QCString> g_tagDict( 5003 );
6837 g_tagDict.setAutoDelete(TRUE);
6843 QCString key( name );
6844 QCString* tag = g_tagDict.find( key );
6850 tag =
new QCString( g_nextTag.copy() );
6851 g_tagDict.insert( key, tag );
6854 char* nxtTag = g_nextTag.rawData() + g_nextTag.length() - 1;
6855 for (
unsigned int i = 0; i < g_nextTag.length(); ++i, --nxtTag )
6857 if ( ( ++(*nxtTag) ) >
'Z' )
6874 return (QCString(fName).right(QCString(ext).length())==ext);
6879 QCString result=fName;
6880 if (result.right(QCString(ext).length())==QCString(ext))
6882 result=result.left(result.length()-QCString(ext).length());
6896 QCString ns = scope.left(i);
6900 scope=*s+scope.right(scope.length()-i);
6903 if (i>0 && ns==scope.left(i))
break;
6910 int i=result.findRev(
'/');
6913 result=result.mid(i+1);
6915 i=result.findRev(
'\\');
6918 result=result.mid(i+1);
6926 static QRegExp wordExp(
"[a-z_A-Z\\x80-\\xFF]+");
6928 while ((i=wordExp.match(s,p,&l))!=-1)
6930 if (s.mid(i,l)==word)
return TRUE;
6938 static QRegExp wordExp(
"[a-z_A-Z\\x80-\\xFF]+");
6940 while ((i=wordExp.match(s,p,&l))!=-1)
6942 if (s.mid(i,l)==word)
6944 if (i>0 && isspace((uchar)s.at(i-1)))
6946 else if (i+l<(
int)s.length() && isspace(s.at(i+l)))
6948 s = s.left(i)+s.mid(i+l);
6966 const char *p = s.data();
6970 int i=0,li=-1,l=s.length();
6974 if (c==
' ' || c==
'\t' || c==
'\r') i++;
6975 else if (c==
'\n') i++,li=i,docLine++;
6985 if (c==
' ' || c==
'\t' || c==
'\r') b--;
6986 else if (c==
'\n') bi=b,b--;
6991 if (li==-1 && bi==-1)
return s;
6996 if (bi<=li)
return 0;
6997 return s.mid(li,bi-li);
7001 void stringToSearchIndex(
const QCString &docBaseUrl,
const QCString &title,
7002 const QCString &str,
bool priority,
const QCString &anchor)
7008 static QRegExp wordPattern(
"[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*");
7010 while ((i=wordPattern.match(str,p,&l))!=-1)
7055 QCString langName = language.lower();
7065 QCString extName = extension.lower();
7066 if (extName.isEmpty())
return FALSE;
7067 if (extName.at(0)!=
'.') extName.prepend(
".");
7068 if (g_extLookup.find(extension)!=0)
7070 g_extLookup.remove(extension);
7073 g_extLookup.insert(extName,
new int(parserId));
7076 err(
"Failed to assign extension %s to parser %s for language %s\n",
7077 extName.data(),p->
parserName,language.data());
7090 g_extLookup.setAutoDelete(TRUE);
7154 int i = fileName.findRev(
'.');
7157 QCString extStr=fileName.right(fileName.length()-i).lower();
7158 if (!extStr.isEmpty())
7160 int *pVal=g_extLookup.find(extStr);
7195 QCString explicitScopePart;
7197 if (qualifierIndex!=-1)
7199 explicitScopePart = name.left(qualifierIndex);
7201 name = name.mid(qualifierIndex+2);
7205 int minDistance = 10000;
7214 for (dli.toFirst();(d=dli.current());++dli)
7220 if (distance!=-1 && distance<minDistance)
7222 minDistance = distance;
7235 if (distance!=-1 && distance<minDistance)
7237 minDistance = distance;
7250 if (bestMatch && bestMatch->
isTypedef())
7262 if (((uchar)c&0xE0)==0xC0)
7266 if (((uchar)c&0xF0)==0xE0)
7270 if (((uchar)c&0xF8)==0xF0)
7274 if (((uchar)c&0xFC)==0xF8)
7278 if (((uchar)c&0xFE)==0xFC)
7289 if (startPos>=len)
return len;
7290 char c = utf8Str[startPos];
7293 if (((uchar)c&0xE0)==0xC0)
7297 if (((uchar)c&0xF0)==0xE0)
7301 if (((uchar)c&0xF8)==0xF0)
7305 if (((uchar)c&0xFC)==0xF8)
7309 if (((uchar)c&0xFE)==0xFC)
7316 static QRegExp re1(
"&#[0-9]+;");
7317 static QRegExp re2(
"&[A-Z_a-z]+;");
7319 int i1 = re1.match(utf8Str,startPos,&l1);
7320 int i2 = re2.match(utf8Str,startPos,&l2);
7330 return startPos+bytes;
7334 const QCString &
doc,
const QCString &fileName,
int lineNr)
7337 if (doc.isEmpty())
return s.data();
7348 int l=result.length();
7349 bool addEllipsis=FALSE;
7353 if (charCnt>=80)
break;
7360 if (result.at(i)>=0 && isspace(result.at(i)))
7364 else if (result.at(i)==
',' ||
7365 result.at(i)==
'.' ||
7372 if (addEllipsis || charCnt==100) result=result.left(i)+
"...";
7373 return result.data();
7380 static QCString
expandAliasRec(
const QCString s,
bool allowRecursion=FALSE);
7407 while ((c=*p) &&
isId(c)) p++;
7427 QList<QCString> args;
7428 args.setAutoDelete(TRUE);
7429 int i,l=(int)argList.length();
7433 char c = argList.at(i);
7434 if (c==
',' && (i==0 || argList.at(i-1)!=
'\\'))
7436 args.append(
new QCString(argList.mid(s,i-s)));
7439 else if (c==
'@' || c==
'\\')
7445 if (l>s) args.append(
new QCString(argList.right(l-s)));
7449 QList<Marker> markerList;
7450 markerList.setAutoDelete(TRUE);
7451 l = aliasValue.length();
7456 if (markerStart==0 && aliasValue.at(i)==
'\\')
7460 else if (markerStart>0 && aliasValue.at(i)>=
'0' && aliasValue.at(i)<=
'9')
7467 if (markerStart>0 && markerEnd>markerStart)
7469 int markerLen = markerEnd-markerStart;
7470 markerList.append(
new Marker(markerStart-1,
7471 atoi(aliasValue.mid(markerStart,markerLen)),markerLen+1));
7483 if (markerStart>0 && markerEnd>markerStart)
7485 int markerLen = markerEnd-markerStart;
7486 markerList.append(
new Marker(markerStart-1,
7487 atoi(aliasValue.mid(markerStart,markerLen)),markerLen+1));
7495 for (i=0;i<(int)markerList.count();i++)
7497 Marker *m = markerList.at(i);
7498 result+=aliasValue.mid(p,m->
pos-p);
7508 result+=aliasValue.right(l-p);
7522 const char *p = s.data();
7526 if (c==
',' && pc!=
'\\')
7538 return result.data();
7544 static QRegExp cmdPat(
"[\\\\@][a-z_A-Z][a-z_A-Z0-9]*");
7547 while ((i=cmdPat.match(value,p,&l))!=-1)
7549 result+=value.mid(p,i-p);
7551 bool hasArgs = !args.isEmpty();
7552 int argsLen = args.length();
7553 QCString cmd = value.mid(i+1,l-1);
7554 QCString cmdNoArgs = cmd;
7559 cmd += QCString().sprintf(
"{%d}",numArgs);
7562 if (numArgs>1 && aliasText==0)
7568 cmd = cmdNoArgs+
"{1}";
7574 if ((allowRecursion || aliasesProcessed.find(cmd)==0) && aliasText)
7577 if (!allowRecursion) aliasesProcessed.insert(cmd,(
void *)0x8);
7578 QCString val = *aliasText;
7586 if (!allowRecursion) aliasesProcessed.remove(cmd);
7588 if (hasArgs) p+=argsLen+2;
7593 result+=value.mid(i,l);
7597 result+=value.right(value.length()-p);
7607 int l = argList.length();
7611 char c = argList.at(i);
7612 if (c==
',' && (i==0 || argList.at(i-1)!=
'\\')) count++;
7613 else if (c==
'@' || c==
'\\')
7628 if (args.at(pos)==
'{')
7630 for (i=pos;i<(int)args.length();i++)
7634 if (args.at(i)==
'{') bc++;
7635 if (args.at(i)==
'}') bc--;
7636 prevChar=args.at(i);
7646 return args.mid(pos+1,i-pos-1);
7656 aliasesProcessed.clear();
7663 QCString
expandAlias(
const QCString &aliasName,
const QCString &aliasValue)
7666 aliasesProcessed.clear();
7668 aliasesProcessed.insert(aliasName,(
void *)0x8);
7682 for (;(a=ali.current());++ali)
7701 #ifdef TRACINGSUPPORT
7702 void *backtraceFrames[128];
7703 int frameCount = backtrace(backtraceFrames, 128);
7704 static char cmd[40960];
7706 p += sprintf(p,
"/usr/bin/atos -p %d ", (
int)getpid());
7707 for (
int x = 0; x < frameCount; x++)
7709 p += sprintf(p,
"%p ", backtraceFrames[x]);
7711 fprintf(stderr,
"========== STACKTRACE START ==============\n");
7712 if (FILE *fp = popen(cmd,
"r"))
7715 while (
size_t len = fread(resBuf, 1,
sizeof(resBuf), fp))
7717 fwrite(resBuf, 1, len, stderr);
7721 fprintf(stderr,
"============ STACKTRACE END ==============\n");
7727 const char *inputEncoding,
const char *outputEncoding)
7729 if (inputEncoding==0 || outputEncoding==0)
return size;
7730 if (qstricmp(inputEncoding,outputEncoding)==0)
return size;
7732 if (cd==(
void *)(-1))
7734 err(
"unsupported character conversion: '%s'->'%s': %s\n"
7735 "Check the INPUT_ENCODING setting in the config file!\n",
7736 inputEncoding,outputEncoding,strerror(errno));
7739 int tmpBufSize=size*4+1;
7740 BufStr tmpBuf(tmpBufSize);
7742 size_t oLeft=tmpBufSize;
7743 char *srcPtr = srcBuf.
data();
7744 char *dstPtr = tmpBuf.
data();
7748 newSize = tmpBufSize-(int)oLeft;
7750 strncpy(srcBuf.
data(),tmpBuf.
data(),newSize);
7755 err(
"%s: failed to translate characters from %s to %s: check INPUT_ENCODING\n",
7756 fileName,inputEncoding,outputEncoding);
7771 QFileInfo fi(fileName);
7772 if (!fi.exists())
return FALSE;
7774 if (filterName.isEmpty() || !
filter)
7777 if (!f.open(IO_ReadOnly))
7779 err(
"could not open file %s\n",fileName);
7785 if (f.readBlock(inBuf.
data(),size)!=size)
7787 err(
"problems while reading file %s\n",fileName);
7793 QCString cmd=filterName+
" \""+fileName+
"\"";
7798 err(
"could not execute filter %s\n",filterName.data());
7801 const int bufSize=1024;
7804 while ((numRead=(
int)fread(buf,1,bufSize,f))>0)
7807 inBuf.
addArray(buf,numRead),size+=numRead;
7817 ((inBuf.
at(0)==-1 && inBuf.
at(1)==-2) ||
7818 (inBuf.
at(0)==-2 && inBuf.
at(1)==-1)
7826 (uchar)inBuf.
at(0)==0xEF &&
7827 (uchar)inBuf.
at(1)==0xBB &&
7828 (uchar)inBuf.
at(2)==0xBF
7843 size=inBuf.
curPos()-start;
7859 static QRegExp re(
"%[A-Z_a-z]");
7861 while ((i=re.match(title,p,&l))!=-1)
7863 tf+=title.mid(p,i-p);
7864 tf+=title.mid(i+1,l-1);
7867 tf+=title.right(title.length()-p);
7880 QStrListIterator it(*patList);
7883 QCString fn = fi.fileName().data();
7884 QCString fp = fi.filePath().data();
7885 QCString afp= fi.absFilePath().data();
7887 for (it.toFirst();(pattern=it.current());++it)
7889 if (!pattern.isEmpty())
7891 int i=pattern.find(
'=');
7892 if (i!=-1) pattern=pattern.left(i);
7894 #if defined(_WIN32) || defined(__MACOSX__) // Windows or MacOSX
7895 QRegExp re(pattern,FALSE,TRUE);
7897 QRegExp re(pattern,TRUE,TRUE);
7899 found = re.match(fn)!=-1 ||
7911 #if 0 // move to HtmlGenerator::writeSummaryLink
7912 void writeSummaryLink(
OutputList &ol,
const char *label,
const char *title,
7913 bool &first,
const char *file)
7943 static bool extLinksInWindow =
Config_getBool(EXT_LINKS_IN_WINDOW);
7944 if (extLinksInWindow)
return "target=\"_blank\" ";
else return "";
7947 QCString
externalRef(
const QCString &relPath,
const QCString &ref,
bool href)
7956 int l = result.length();
7957 if (!relPath.isEmpty() && l>0 && result.at(0)==
'.')
7959 result.prepend(relPath);
7960 l+=relPath.length();
7963 result.prepend(
"doxygen=\""+ref+
":");
7966 if (l>0 && result.at(l-1)!=
'/') result+=
'/';
7967 if (!href) result.append(
"\" ");
7988 fileName=(QCString)dir+
"/"+data->
name;
7990 if (f.open(IO_WriteOnly))
7998 fprintf(stderr,
"Warning: Cannot open file %s for writing\n",data->
name);
8014 if (s.isEmpty())
return result;
8015 static QRegExp re(
"##[0-9A-Fa-f][0-9A-Fa-f]");
8016 static const char hex[] =
"0123456789ABCDEF";
8020 int i,l,sl=s.length(),p=0;
8021 while ((i=re.match(s,p,&l))!=-1)
8023 result+=s.mid(p,i-p);
8024 QCString lumStr = s.mid(i+2,l-2);
8025 #define HEXTONUM(x) (((x)>='0' && (x)<='9') ? ((x)-'0') : \
8026 ((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \
8027 ((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0)
8033 pow(level/255.0,gamma/100.0),&r,&g,&b);
8034 red = (int)(r*255.0);
8035 green = (int)(g*255.0);
8036 blue = (int)(b*255.0);
8039 colStr[1]=hex[red>>4];
8040 colStr[2]=hex[red&0xf];
8041 colStr[3]=hex[green>>4];
8042 colStr[4]=hex[green&0xf];
8043 colStr[5]=hex[blue>>4];
8044 colStr[6]=hex[blue&0xf];
8050 result+=s.right(sl-p);
8057 bool copyFile(
const QCString &src,
const QCString &dest)
8060 if (sf.open(IO_ReadOnly))
8064 if (df.open(IO_WriteOnly))
8066 char *buffer =
new char[fi.size()];
8067 sf.readBlock(buffer,fi.size());
8068 df.writeBlock(buffer,fi.size());
8074 err(
"could not write to file %s\n",dest.data());
8080 err(
"could not open user specified file %s\n",src.data());
8097 int m1 = text.find(marker);
8098 if (m1==-1)
return result;
8099 int m2 = text.find(marker,m1+marker.length());
8100 if (m2==-1)
return result;
8104 while (!found && (i=text.find(
'\n',p))!=-1)
8106 found = (p<=m1 && m1<i);
8113 while ((i=text.find(
'\n',p))!=-1)
8129 return l2>l1 ? text.mid(l1,l2-l1) : QCString();
8142 int m1 = text.find(marker);
8143 if (m1==-1)
return result;
8146 while (!found && (i=text.find(
'\n',p))!=-1)
8148 found = (p<=m1 && m1<i);
8201 QCString result = url;
8202 if (!relPath.isEmpty() &&
8203 url.left(5)!=
"http:" && url.left(6)!=
"https:" &&
8204 url.left(4)!=
"ftp:" && url.left(5)!=
"file:")
8206 result.prepend(relPath);
8219 (prot==
Private && extractPrivate) ||
8220 (prot==
Package && extractPackage);
8227 if (s.isEmpty())
return s;
8231 const char *p=s.data();
8234 int minIndent=1000000;
8235 bool searchIndent=TRUE;
8239 if (c==
'\t') indent+=tabSize - (indent%tabSize);
8240 else if (c==
'\n') indent=0,searchIndent=TRUE;
8241 else if (c==
' ') indent++;
8242 else if (searchIndent)
8245 if (indent<minIndent) minIndent=indent;
8250 if (minIndent==0)
return s;
8263 else if (indent<minIndent)
8267 int newIndent = indent+tabSize-(indent%tabSize);
8288 return result.data();
8297 return ( ((allExternals && fd->
isLinkable()) ||
8306 static bool referencedByRelation =
Config_getBool(REFERENCED_BY_RELATION);
8307 static bool referencesRelation =
Config_getBool(REFERENCES_RELATION);
8357 const int length = s.length();
8358 if (idx >= length) {
return 0; }
8359 const uint c0 = (uchar)s.at(idx);
8360 if ( c0 < 0xC2 || c0 >= 0xF8 )
8364 if (idx+1 >= length) {
return 0; }
8365 const uint c1 = ((uchar)s.at(idx+1)) & 0x3f;
8368 return ((c0 & 0x1f) << 6) | c1;
8370 if (idx+2 >= length) {
return 0; }
8371 const uint c2 = ((uchar)s.at(idx+2)) & 0x3f;
8374 return ((c0 & 0x0f) << 12) | (c1 << 6) | c2;
8376 if (idx+3 >= length) {
return 0; }
8378 const uint c3 = ((uchar)s.at(idx+3)) & 0x3f;
8379 return ((c0 & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3;
8394 return v < 0x7f ? tolower( v ) : v;
8409 return v < 0x7f ? toupper( v ) : v;
8420 for (cnli.toFirst();(cnd=cnli.current());++cnli)
8422 if (cnd->isLinkableInProject() && cnd->localName().find(
'@')==-1)
8436 for (;(cd=cli.current());++cli)
8438 if (cd->isLinkableInProject() && cd->templateMaster()==0)
8459 QRegExp re(
"\\[[^\\]]+\\]");
8461 if (re.match(docs,0,&l)==0)
8463 int inPos = docs.find(
"in", 1,FALSE);
8464 int outPos = docs.find(
"out",1,FALSE);
8465 bool input = inPos!=-1 && inPos<l;
8466 bool output = outPos!=-1 && outPos<l;
8467 if (input || output)
8470 if (input && output)
return "[in,out]";
8471 else if (input)
return "[in]";
8472 else if (output)
return "[out]";
8502 *outListType1=inListType;
8680 imgExt = imgExt.replace( QRegExp(
":.*"),
"" );
8686 bool fileOpened=FALSE;
8687 bool writeToStdout=(outFile[0]==
'-' && outFile[1]==
'\0');
8690 fileOpened = f.open(IO_WriteOnly,stdout);
8694 QFileInfo fi(outFile);
8698 QFileInfo backup(fi.fileName()+
".bak");
8699 if (backup.exists())
8700 dir.remove(backup.fileName());
8701 dir.rename(fi.fileName(),fi.fileName()+
".bak");
8704 fileOpened = f.open(IO_WriteOnly|IO_Translate);
8713 if (!extraPackages.isEmpty())
8715 t <<
"% Packages requested by user\n";
8716 const char *pkgName=extraPackages.first();
8719 if ((pkgName[0] ==
'[') || (pkgName[0] ==
'{'))
8720 t <<
"\\usepackage" << pkgName <<
"\n";
8722 t <<
"\\usepackage{" << pkgName <<
"}\n";
8723 pkgName=extraPackages.next();