Commit bca6baee authored by Dimitri van Heesch's avatar Dimitri van Heesch

Bug 705910 - Indexing and searching cannot treat non ASCII identifiers

parent f6bc941e
...@@ -174,7 +174,7 @@ QHP_SECT_FILTER_ATTRS = ...@@ -174,7 +174,7 @@ QHP_SECT_FILTER_ATTRS =
QHG_LOCATION = QHG_LOCATION =
GENERATE_ECLIPSEHELP = YES GENERATE_ECLIPSEHELP = YES
ECLIPSE_DOC_ID = org.doxygen.qtools ECLIPSE_DOC_ID = org.doxygen.qtools
DISABLE_INDEX = YES DISABLE_INDEX = NO
GENERATE_TREEVIEW = YES GENERATE_TREEVIEW = YES
ENUM_VALUES_PER_LINE = 4 ENUM_VALUES_PER_LINE = 4
TREEVIEW_WIDTH = 250 TREEVIEW_WIDTH = 250
......
...@@ -119,23 +119,28 @@ static void endIndexHierarchy(OutputList &ol,int level) ...@@ -119,23 +119,28 @@ static void endIndexHierarchy(OutputList &ol,int level)
class MemberIndexList : public QList<MemberDef> class MemberIndexList : public QList<MemberDef>
{ {
public: public:
MemberIndexList() : QList<MemberDef>() {} typedef MemberDef ElementType;
MemberIndexList(uint letter) : QList<MemberDef>(), m_letter(letter) {}
~MemberIndexList() {} ~MemberIndexList() {}
int compareItems(QCollection::Item item1, QCollection::Item item2) int compareItems(QCollection::Item item1, QCollection::Item item2)
{ {
MemberDef *md1=(MemberDef *)item1; MemberDef *md1=(MemberDef *)item1;
MemberDef *md2=(MemberDef *)item2; MemberDef *md2=(MemberDef *)item2;
return qstricmp(md1->name(),md2->name()); int result = qstricmp(md1->name(),md2->name());
if (result==0)
{
result = qstricmp(md1->qualifiedName(),md2->qualifiedName());
}
return result;
} }
uint letter() const { return m_letter; }
private:
uint m_letter;
}; };
#define MEMBER_INDEX_ENTRIES 256 static LetterToIndexMap<MemberIndexList> g_memberIndexLetterUsed[CMHL_Total];
static LetterToIndexMap<MemberIndexList> g_fileIndexLetterUsed[FMHL_Total];
static MemberIndexList g_memberIndexLetterUsed[CMHL_Total][MEMBER_INDEX_ENTRIES]; static LetterToIndexMap<MemberIndexList> g_namespaceIndexLetterUsed[NMHL_Total];
static MemberIndexList g_fileIndexLetterUsed[FMHL_Total][MEMBER_INDEX_ENTRIES];
static MemberIndexList g_namespaceIndexLetterUsed[NMHL_Total][MEMBER_INDEX_ENTRIES];
//static bool g_classIndexLetterUsed[CHL_Total][256];
const int maxItemsBeforeQuickIndex = MAX_ITEMS_BEFORE_QUICK_INDEX; const int maxItemsBeforeQuickIndex = MAX_ITEMS_BEFORE_QUICK_INDEX;
...@@ -1690,21 +1695,39 @@ static void writeAnnotatedClassList(OutputList &ol) ...@@ -1690,21 +1695,39 @@ static void writeAnnotatedClassList(OutputList &ol)
ol.endIndexList(); ol.endIndexList();
} }
static QCString letterToLabel(char startLetter) static QCString letterToLabel(uint startLetter)
{ {
QCString s(5); char s[10];
if (isId(startLetter)) if (startLetter>0x20 && startLetter<=0x7f) // printable ASCII character
{ {
s[0]=startLetter; s[1]=0; s[0]=(char)startLetter;
s[1]=0;
} }
else else
{ {
const char hex[]="0123456789abcdef"; const char hex[]="0123456789abcdef";
s[0]='0'; int i=0;
s[1]='x'; s[i++]='0';
s[2]=hex[startLetter>>4]; s[i++]='x';
s[3]=hex[startLetter&0xF]; if (startLetter>(1<<24)) // 4 byte character
s[4]=0; {
s[i++]=hex[(startLetter>>28)&0xf];
s[i++]=hex[(startLetter>>24)&0xf];
}
if (startLetter>(1<<16)) // 3 byte character
{
s[i++]=hex[(startLetter>>20)&0xf];
s[i++]=hex[(startLetter>>16)&0xf];
}
if (startLetter>(1<<8)) // 2 byte character
{
s[i++]=hex[(startLetter>>12)&0xf];
s[i++]=hex[(startLetter>>8)&0xf];
}
// one byte character
s[i++]=hex[(startLetter>>4)&0xf];
s[i++]=hex[(startLetter>>0)&0xf];
s[i++]=0;
} }
return s; return s;
} }
...@@ -1714,7 +1737,9 @@ static QCString letterToLabel(char startLetter) ...@@ -1714,7 +1737,9 @@ static QCString letterToLabel(char startLetter)
/** Special class list where sorting takes IGNORE_PREFIX into account. */ /** Special class list where sorting takes IGNORE_PREFIX into account. */
class PrefixIgnoreClassList : public ClassList class PrefixIgnoreClassList : public ClassList
{ {
public: public:
typedef ClassDef ElementType;
PrefixIgnoreClassList(uint letter) : m_letter(letter) {}
virtual int compareItems(QCollection::Item item1, QCollection::Item item2) virtual int compareItems(QCollection::Item item1, QCollection::Item item2)
{ {
ClassDef *c1=(ClassDef *)item1; ClassDef *c1=(ClassDef *)item1;
...@@ -1724,25 +1749,28 @@ public: ...@@ -1724,25 +1749,28 @@ public:
QCString n2 = c2->className(); QCString n2 = c2->className();
return qstricmp (n1.data()+getPrefixIndex(n1), n2.data()+getPrefixIndex(n2)); return qstricmp (n1.data()+getPrefixIndex(n1), n2.data()+getPrefixIndex(n2));
} }
uint letter() const { return m_letter; }
private:
uint m_letter;
}; };
/** Class representing a cell in the alphabetical class index. */ /** Class representing a cell in the alphabetical class index. */
class AlphaIndexTableCell class AlphaIndexTableCell
{ {
public: public:
AlphaIndexTableCell(int row,int col,uchar letter,ClassDef *cd) : AlphaIndexTableCell(int row,int col,uint letter,ClassDef *cd) :
m_letter(letter), m_class(cd), m_row(row), m_col(col) m_letter(letter), m_class(cd), m_row(row), m_col(col)
{ //printf("AlphaIndexTableCell(%d,%d,%c,%s)\n",row,col,letter!=0 ? letter: '-', { //printf("AlphaIndexTableCell(%d,%d,%c,%s)\n",row,col,letter!=0 ? letter: '-',
// cd!=(ClassDef*)0x8 ? cd->name().data() : "<null>"); // cd!=(ClassDef*)0x8 ? cd->name().data() : "<null>");
} }
ClassDef *classDef() const { return m_class; } ClassDef *classDef() const { return m_class; }
uchar letter() const { return m_letter; } uint letter() const { return m_letter; }
int row() const { return m_row; } int row() const { return m_row; }
int column() const { return m_col; } int column() const { return m_col; }
private: private:
uchar m_letter; uint m_letter;
ClassDef *m_class; ClassDef *m_class;
int m_row; int m_row;
int m_col; int m_col;
...@@ -1770,12 +1798,31 @@ class AlphaIndexTableColumns : public QList<AlphaIndexTableRows> ...@@ -1770,12 +1798,31 @@ class AlphaIndexTableColumns : public QList<AlphaIndexTableRows>
AlphaIndexTableColumns() { setAutoDelete(TRUE); } AlphaIndexTableColumns() { setAutoDelete(TRUE); }
}; };
class UsedIndexLetters : public SIntDict<uint>
{
public:
UsedIndexLetters() : SIntDict<uint>(257) { setAutoDelete(TRUE); }
int compareItems( QCollection::Item item1, QCollection::Item item2)
{
int *p1=(int *)item1;
int *p2=(int *)item2;
return *p1 - *p2; // subtracting is done by int not uint.
}
void add(uint letter)
{
uint *v = find(letter);
if (v==0)
{
append(letter,new uint(letter));
}
}
};
// write an alphabetical index of all class with a header for each letter // write an alphabetical index of all class with a header for each letter
static void writeAlphabeticalClassList(OutputList &ol) static void writeAlphabeticalClassList(OutputList &ol)
{ {
// What starting letters are used // What starting letters are used
bool indexLetterUsed[256]; UsedIndexLetters indexLettersUsed;
memset (indexLetterUsed, 0, sizeof (indexLetterUsed));
// first count the number of headers // first count the number of headers
ClassSDict::Iterator cli(*Doxygen::classSDict); ClassSDict::Iterator cli(*Doxygen::classSDict);
...@@ -1791,24 +1838,25 @@ static void writeAlphabeticalClassList(OutputList &ol) ...@@ -1791,24 +1838,25 @@ static void writeAlphabeticalClassList(OutputList &ol)
int index = getPrefixIndex(cd->className()); int index = getPrefixIndex(cd->className());
//printf("name=%s index=%d %d\n",cd->className().data(),index,cd->protection()); //printf("name=%s index=%d %d\n",cd->className().data(),index,cd->protection());
startLetter=toupper(cd->className().at(index))&0xFF; startLetter=getUtf8CodeToUpper(cd->className(),index);
indexLetterUsed[startLetter] = true; indexLettersUsed.add(startLetter);
} }
} }
indexLettersUsed.sort();
// write quick link index (row of letters) // write quick link index (row of letters)
QCString alphaLinks = "<div class=\"qindex\">"; QCString alphaLinks = "<div class=\"qindex\">";
int l; SIntDict<uint>::Iterator it(indexLettersUsed);
for (l=0; l<256; l++) uint *pLetter;
{ for (it.toFirst();(pLetter=it.current());++it)
if (indexLetterUsed[l])
{ {
if (headerItems) alphaLinks += "&#160;|&#160;"; if (headerItems) alphaLinks += "&#160;|&#160;";
headerItems++; headerItems++;
QCString li = letterToLabel(*pLetter);
QCString ls = QString(QChar(*pLetter)).utf8();
alphaLinks += (QCString)"<a class=\"qindex\" href=\"#letter_" + alphaLinks += (QCString)"<a class=\"qindex\" href=\"#letter_" +
(char)l + "\">" + li + "\">" +
(char)l + "</a>"; ls + "</a>";
}
} }
alphaLinks += "</div>\n"; alphaLinks += "</div>\n";
ol.writeString(alphaLinks); ol.writeString(alphaLinks);
...@@ -1825,7 +1873,7 @@ static void writeAlphabeticalClassList(OutputList &ol) ...@@ -1825,7 +1873,7 @@ static void writeAlphabeticalClassList(OutputList &ol)
// headerItems,totalItems,columns,rows,itemsInLastRow); // headerItems,totalItems,columns,rows,itemsInLastRow);
// Keep a list of classes for each starting letter // Keep a list of classes for each starting letter
PrefixIgnoreClassList classesByLetter[256]; LetterToIndexMap<PrefixIgnoreClassList> classesByLetter;
AlphaIndexTableColumns tableColumns; AlphaIndexTableColumns tableColumns;
// fill the columns with the class list (row elements in each column, // fill the columns with the class list (row elements in each column,
...@@ -1841,16 +1889,20 @@ static void writeAlphabeticalClassList(OutputList &ol) ...@@ -1841,16 +1889,20 @@ static void writeAlphabeticalClassList(OutputList &ol)
if (cd->isLinkableInProject() && cd->templateMaster()==0) if (cd->isLinkableInProject() && cd->templateMaster()==0)
{ {
int index = getPrefixIndex(cd->className()); int index = getPrefixIndex(cd->className());
startLetter=toupper(cd->className().at(index))&0xFF; startLetter=getUtf8Code(cd->className(),index);
// Do some sorting again, since the classes are sorted by name with // Do some sorting again, since the classes are sorted by name with
// prefix, which should be ignored really. // prefix, which should be ignored really.
if (cd->getLanguage()==SrcLangExt_VHDL) if (cd->getLanguage()==SrcLangExt_VHDL)
{ {
if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS )// no architecture if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS )// no architecture
classesByLetter[startLetter].inSort(cd); {
classesByLetter.append(startLetter,cd);
}
} }
else else
classesByLetter[startLetter].inSort(cd); {
classesByLetter.append(startLetter,cd);
}
} }
} }
...@@ -1871,27 +1923,31 @@ static void writeAlphabeticalClassList(OutputList &ol) ...@@ -1871,27 +1923,31 @@ static void writeAlphabeticalClassList(OutputList &ol)
AlphaIndexTableRows *tableRows = new AlphaIndexTableRows; AlphaIndexTableRows *tableRows = new AlphaIndexTableRows;
tableColumns.append(tableRows); tableColumns.append(tableRows);
int col=0,row=0,maxRows=0; int col=0,row=0,maxRows=0;
for (l=0; l<256; l++) PrefixIgnoreClassList *cl;
{ SIntDict<PrefixIgnoreClassList>::Iterator lit(classesByLetter);
if (classesByLetter[l].count()>0) for (lit.toFirst();(cl=lit.current());++lit)
{ {
uint l = cl->letter();
// add special header cell // add special header cell
tableRows->append(new AlphaIndexTableCell(row,col,(uchar)l,(ClassDef*)0x8)); tableRows->append(new AlphaIndexTableCell(row,col,l,(ClassDef*)0x8));
row++; row++;
tableRows->append(new AlphaIndexTableCell(row,col,0,(ClassDef*)0x8)); tableRows->append(new AlphaIndexTableCell(row,col,0,(ClassDef*)0x8));
row++; row++;
tableRows->append(new AlphaIndexTableCell(row,col,0,classesByLetter[l].at(0))); ClassListIterator cit(*cl);
cit.toFirst();
ClassDef *cd = cit.current();
++cit;
tableRows->append(new AlphaIndexTableCell(row,col,0,cd));
row++; row++;
NEXT_ROW(); NEXT_ROW();
for (i=1; i<(int)classesByLetter[l].count(); i++) for (;(cd=cit.current()); ++cit)
{ {
// add normal cell // add normal cell
tableRows->append(new AlphaIndexTableCell(row,col,0,classesByLetter[l].at(i))); tableRows->append(new AlphaIndexTableCell(row,col,0,cd));
row++; row++;
NEXT_ROW(); NEXT_ROW();
} }
} }
}
// create row iterators for each column // create row iterators for each column
AlphaIndexTableRowsIterator **colIterators = new AlphaIndexTableRowsIterator*[columns]; AlphaIndexTableRowsIterator **colIterators = new AlphaIndexTableRowsIterator*[columns];
...@@ -1936,7 +1992,7 @@ static void writeAlphabeticalClassList(OutputList &ol) ...@@ -1936,7 +1992,7 @@ static void writeAlphabeticalClassList(OutputList &ol)
ol.writeString("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">" ol.writeString("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"
"<tr>" "<tr>"
"<td><div class=\"ah\">&#160;&#160;"); "<td><div class=\"ah\">&#160;&#160;");
ol.writeString(s); ol.writeString(QString(QChar(cell->letter())).utf8());
ol.writeString( "&#160;&#160;</div>" ol.writeString( "&#160;&#160;</div>"
"</td>" "</td>"
"</tr>" "</tr>"
...@@ -2164,14 +2220,9 @@ static void writeNamespaceLinkForMember(OutputList &ol,MemberDef *md,const char ...@@ -2164,14 +2220,9 @@ static void writeNamespaceLinkForMember(OutputList &ol,MemberDef *md,const char
} }
static void writeMemberList(OutputList &ol,bool useSections,int page, static void writeMemberList(OutputList &ol,bool useSections,int page,
MemberIndexList memberLists[MEMBER_INDEX_ENTRIES], const LetterToIndexMap<MemberIndexList> &memberLists,
DefinitionIntf::DefType type) DefinitionIntf::DefType type)
{ {
int pi;
// page==-1 => write all member indices to one page (used when total members is small)
// page!=-1 => write all member for this page only (used when total member is large)
int startIndex = page==-1 ? 0 : page;
int endIndex = page==-1 ? MEMBER_INDEX_ENTRIES-1 : page;
ASSERT((int)type<3); ASSERT((int)type<3);
typedef void (*writeLinkForMember_t)(OutputList &ol,MemberDef *md,const char *separator, typedef void (*writeLinkForMember_t)(OutputList &ol,MemberDef *md,const char *separator,
...@@ -2189,10 +2240,16 @@ static void writeMemberList(OutputList &ol,bool useSections,int page, ...@@ -2189,10 +2240,16 @@ static void writeMemberList(OutputList &ol,bool useSections,int page,
bool first=TRUE; bool first=TRUE;
bool firstSection=TRUE; bool firstSection=TRUE;
bool firstItem=TRUE; bool firstItem=TRUE;
for (pi=startIndex; pi<=endIndex; pi++) // page==-1 => pi=[0..127], page!=-1 => pi=page MemberIndexList *ml;
SIntDict<MemberIndexList>::Iterator it(memberLists);
for (it.toFirst();(ml=it.current());++it)
{ {
MemberIndexList *ml = &memberLists[pi]; if (page!=-1)
if (ml->count()==0) continue; {
ml = memberLists[page];
it.toLast();
}
if (ml==0 || ml->count()==0) continue;
ml->sort(); ml->sort();
QListIterator<MemberDef> mli(*ml); QListIterator<MemberDef> mli(*ml);
MemberDef *md; MemberDef *md;
...@@ -2211,10 +2268,8 @@ static void writeMemberList(OutputList &ol,bool useSections,int page, ...@@ -2211,10 +2268,8 @@ static void writeMemberList(OutputList &ol,bool useSections,int page,
{ {
if (!firstItem) ol.endItemListItem(); if (!firstItem) ol.endItemListItem();
if (!firstSection) ol.endItemList(); if (!firstSection) ol.endItemList();
char cl[2]; QCString cs = letterToLabel(ml->letter());
cl[0] = tolower(name.at(startIndex)); QCString cl = QString(QChar(ml->letter())).utf8();
cl[1] = 0;
QCString cs = letterToLabel(cl[0]);
QCString anchor=(QCString)"index_"+cs; QCString anchor=(QCString)"index_"+cs;
QCString title=(QCString)"- "+cl+" -"; QCString title=(QCString)"- "+cl+" -";
ol.startSection(anchor,title,SectionInfo::Subsection); ol.startSection(anchor,title,SectionInfo::Subsection);
...@@ -2260,15 +2315,11 @@ static void writeMemberList(OutputList &ol,bool useSections,int page, ...@@ -2260,15 +2315,11 @@ static void writeMemberList(OutputList &ol,bool useSections,int page,
void initClassMemberIndices() void initClassMemberIndices()
{ {
int i=0;
int j=0; int j=0;
for (j=0;j<CMHL_Total;j++) for (j=0;j<CMHL_Total;j++)
{ {
documentedClassMembers[j]=0; documentedClassMembers[j]=0;
for (i=0;i<MEMBER_INDEX_ENTRIES;i++) g_memberIndexLetterUsed[j].clear();
{
g_memberIndexLetterUsed[j][i].clear();
}
} }
} }
...@@ -2286,8 +2337,7 @@ void addClassMemberNameToIndex(MemberDef *md) ...@@ -2286,8 +2337,7 @@ void addClassMemberNameToIndex(MemberDef *md)
{ {
QCString n = md->name(); QCString n = md->name();
int index = getPrefixIndex(n); int index = getPrefixIndex(n);
uchar charCode = (uchar)n.at(index); uint letter = getUtf8CodeToLower(n,index);
uint letter = charCode<128 ? tolower(charCode) : charCode;
if (!n.isEmpty()) if (!n.isEmpty())
{ {
bool isFriendToHide = hideFriendCompounds && bool isFriendToHide = hideFriendCompounds &&
...@@ -2296,48 +2346,48 @@ void addClassMemberNameToIndex(MemberDef *md) ...@@ -2296,48 +2346,48 @@ void addClassMemberNameToIndex(MemberDef *md)
QCString(md->typeString())=="friend union"); QCString(md->typeString())=="friend union");
if (!(md->isFriend() && isFriendToHide)) if (!(md->isFriend() && isFriendToHide))
{ {
g_memberIndexLetterUsed[CMHL_All][letter].append(md); g_memberIndexLetterUsed[CMHL_All].append(letter,md);
documentedClassMembers[CMHL_All]++; documentedClassMembers[CMHL_All]++;
} }
if (md->isFunction() || md->isSlot() || md->isSignal()) if (md->isFunction() || md->isSlot() || md->isSignal())
{ {
g_memberIndexLetterUsed[CMHL_Functions][letter].append(md); g_memberIndexLetterUsed[CMHL_Functions].append(letter,md);
documentedClassMembers[CMHL_Functions]++; documentedClassMembers[CMHL_Functions]++;
} }
else if (md->isVariable()) else if (md->isVariable())
{ {
g_memberIndexLetterUsed[CMHL_Variables][letter].append(md); g_memberIndexLetterUsed[CMHL_Variables].append(letter,md);
documentedClassMembers[CMHL_Variables]++; documentedClassMembers[CMHL_Variables]++;
} }
else if (md->isTypedef()) else if (md->isTypedef())
{ {
g_memberIndexLetterUsed[CMHL_Typedefs][letter].append(md); g_memberIndexLetterUsed[CMHL_Typedefs].append(letter,md);
documentedClassMembers[CMHL_Typedefs]++; documentedClassMembers[CMHL_Typedefs]++;
} }
else if (md->isEnumerate()) else if (md->isEnumerate())
{ {
g_memberIndexLetterUsed[CMHL_Enums][letter].append(md); g_memberIndexLetterUsed[CMHL_Enums].append(letter,md);
documentedClassMembers[CMHL_Enums]++; documentedClassMembers[CMHL_Enums]++;
} }
else if (md->isEnumValue()) else if (md->isEnumValue())
{ {
g_memberIndexLetterUsed[CMHL_EnumValues][letter].append(md); g_memberIndexLetterUsed[CMHL_EnumValues].append(letter,md);
documentedClassMembers[CMHL_EnumValues]++; documentedClassMembers[CMHL_EnumValues]++;
} }
else if (md->isProperty()) else if (md->isProperty())
{ {
g_memberIndexLetterUsed[CMHL_Properties][letter].append(md); g_memberIndexLetterUsed[CMHL_Properties].append(letter,md);
documentedClassMembers[CMHL_Properties]++; documentedClassMembers[CMHL_Properties]++;
} }
else if (md->isEvent()) else if (md->isEvent())
{ {
g_memberIndexLetterUsed[CMHL_Events][letter].append(md); g_memberIndexLetterUsed[CMHL_Events].append(letter,md);
documentedClassMembers[CMHL_Events]++; documentedClassMembers[CMHL_Events]++;
} }
else if (md->isRelated() || md->isForeign() || else if (md->isRelated() || md->isForeign() ||
(md->isFriend() && !isFriendToHide)) (md->isFriend() && !isFriendToHide))
{ {
g_memberIndexLetterUsed[CMHL_Related][letter].append(md); g_memberIndexLetterUsed[CMHL_Related].append(letter,md);
documentedClassMembers[CMHL_Related]++; documentedClassMembers[CMHL_Related]++;
} }
} }
...@@ -2348,15 +2398,11 @@ void addClassMemberNameToIndex(MemberDef *md) ...@@ -2348,15 +2398,11 @@ void addClassMemberNameToIndex(MemberDef *md)
void initNamespaceMemberIndices() void initNamespaceMemberIndices()
{ {
int i=0;
int j=0; int j=0;
for (j=0;j<NMHL_Total;j++) for (j=0;j<NMHL_Total;j++)
{ {
documentedNamespaceMembers[j]=0; documentedNamespaceMembers[j]=0;
for (i=0;i<MEMBER_INDEX_ENTRIES;i++) g_namespaceIndexLetterUsed[j].clear();
{
g_namespaceIndexLetterUsed[j][i].clear();
}
} }
} }
...@@ -2367,36 +2413,35 @@ void addNamespaceMemberNameToIndex(MemberDef *md) ...@@ -2367,36 +2413,35 @@ void addNamespaceMemberNameToIndex(MemberDef *md)
{ {
QCString n = md->name(); QCString n = md->name();
int index = getPrefixIndex(n); int index = getPrefixIndex(n);
uchar charCode = (uchar)n.at(index); uint letter = getUtf8CodeToLower(n,index);
uint letter = charCode<128 ? tolower(charCode) : charCode;
if (!n.isEmpty()) if (!n.isEmpty())
{ {
g_namespaceIndexLetterUsed[NMHL_All][letter].append(md); g_namespaceIndexLetterUsed[NMHL_All].append(letter,md);
documentedNamespaceMembers[NMHL_All]++; documentedNamespaceMembers[NMHL_All]++;
if (md->isFunction()) if (md->isFunction())
{ {
g_namespaceIndexLetterUsed[NMHL_Functions][letter].append(md); g_namespaceIndexLetterUsed[NMHL_Functions].append(letter,md);
documentedNamespaceMembers[NMHL_Functions]++; documentedNamespaceMembers[NMHL_Functions]++;
} }
else if (md->isVariable()) else if (md->isVariable())
{ {
g_namespaceIndexLetterUsed[NMHL_Variables][letter].append(md); g_namespaceIndexLetterUsed[NMHL_Variables].append(letter,md);
documentedNamespaceMembers[NMHL_Variables]++; documentedNamespaceMembers[NMHL_Variables]++;
} }
else if (md->isTypedef()) else if (md->isTypedef())
{ {
g_namespaceIndexLetterUsed[NMHL_Typedefs][letter].append(md); g_namespaceIndexLetterUsed[NMHL_Typedefs].append(letter,md);
documentedNamespaceMembers[NMHL_Typedefs]++; documentedNamespaceMembers[NMHL_Typedefs]++;
} }
else if (md->isEnumerate()) else if (md->isEnumerate())
{ {
g_namespaceIndexLetterUsed[NMHL_Enums][letter].append(md); g_namespaceIndexLetterUsed[NMHL_Enums].append(letter,md);
documentedNamespaceMembers[NMHL_Enums]++; documentedNamespaceMembers[NMHL_Enums]++;
} }
else if (md->isEnumValue()) else if (md->isEnumValue())
{ {
g_namespaceIndexLetterUsed[NMHL_EnumValues][letter].append(md); g_namespaceIndexLetterUsed[NMHL_EnumValues].append(letter,md);
documentedNamespaceMembers[NMHL_EnumValues]++; documentedNamespaceMembers[NMHL_EnumValues]++;
} }
} }
...@@ -2407,15 +2452,11 @@ void addNamespaceMemberNameToIndex(MemberDef *md) ...@@ -2407,15 +2452,11 @@ void addNamespaceMemberNameToIndex(MemberDef *md)
void initFileMemberIndices() void initFileMemberIndices()
{ {
int i=0;
int j=0; int j=0;
for (j=0;j<NMHL_Total;j++) for (j=0;j<NMHL_Total;j++)
{ {
documentedFileMembers[j]=0; documentedFileMembers[j]=0;
for (i=0;i<MEMBER_INDEX_ENTRIES;i++) g_fileIndexLetterUsed[j].clear();
{
g_fileIndexLetterUsed[j][i].clear();
}
} }
} }
...@@ -2426,41 +2467,40 @@ void addFileMemberNameToIndex(MemberDef *md) ...@@ -2426,41 +2467,40 @@ void addFileMemberNameToIndex(MemberDef *md)
{ {
QCString n = md->name(); QCString n = md->name();
int index = getPrefixIndex(n); int index = getPrefixIndex(n);
uchar charCode = (uchar)n.at(index); uint letter = getUtf8CodeToLower(n,index);
uint letter = charCode<128 ? tolower(charCode) : charCode;
if (!n.isEmpty()) if (!n.isEmpty())
{ {
g_fileIndexLetterUsed[FMHL_All][letter].append(md); g_fileIndexLetterUsed[FMHL_All].append(letter,md);
documentedFileMembers[FMHL_All]++; documentedFileMembers[FMHL_All]++;
if (md->isFunction()) if (md->isFunction())
{ {
g_fileIndexLetterUsed[FMHL_Functions][letter].append(md); g_fileIndexLetterUsed[FMHL_Functions].append(letter,md);
documentedFileMembers[FMHL_Functions]++; documentedFileMembers[FMHL_Functions]++;
} }
else if (md->isVariable()) else if (md->isVariable())
{ {
g_fileIndexLetterUsed[FMHL_Variables][letter].append(md); g_fileIndexLetterUsed[FMHL_Variables].append(letter,md);
documentedFileMembers[FMHL_Variables]++; documentedFileMembers[FMHL_Variables]++;
} }
else if (md->isTypedef()) else if (md->isTypedef())
{ {
g_fileIndexLetterUsed[FMHL_Typedefs][letter].append(md); g_fileIndexLetterUsed[FMHL_Typedefs].append(letter,md);
documentedFileMembers[FMHL_Typedefs]++; documentedFileMembers[FMHL_Typedefs]++;
} }
else if (md->isEnumerate()) else if (md->isEnumerate())
{ {
g_fileIndexLetterUsed[FMHL_Enums][letter].append(md); g_fileIndexLetterUsed[FMHL_Enums].append(letter,md);
documentedFileMembers[FMHL_Enums]++; documentedFileMembers[FMHL_Enums]++;
} }
else if (md->isEnumValue()) else if (md->isEnumValue())
{ {
g_fileIndexLetterUsed[FMHL_EnumValues][letter].append(md); g_fileIndexLetterUsed[FMHL_EnumValues].append(letter,md);
documentedFileMembers[FMHL_EnumValues]++; documentedFileMembers[FMHL_EnumValues]++;
} }
else if (md->isDefine()) else if (md->isDefine())
{ {
g_fileIndexLetterUsed[FMHL_Defines][letter].append(md); g_fileIndexLetterUsed[FMHL_Defines].append(letter,md);
documentedFileMembers[FMHL_Defines]++; documentedFileMembers[FMHL_Defines]++;
} }
} }
...@@ -2470,18 +2510,18 @@ void addFileMemberNameToIndex(MemberDef *md) ...@@ -2470,18 +2510,18 @@ void addFileMemberNameToIndex(MemberDef *md)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static void writeQuickMemberIndex(OutputList &ol, static void writeQuickMemberIndex(OutputList &ol,
MemberIndexList charUsed[MEMBER_INDEX_ENTRIES],int page, const LetterToIndexMap<MemberIndexList> &charUsed,uint page,
QCString fullName,bool multiPage) QCString fullName,bool multiPage)
{ {
bool first=TRUE; bool first=TRUE;
int i;
startQuickIndexList(ol,TRUE); startQuickIndexList(ol,TRUE);
for (i=33;i<127;i++) SIntDict<MemberIndexList>::Iterator it(charUsed);
{ MemberIndexList *ml;
char is[2];is[0]=(char)i;is[1]='\0'; for (it.toFirst();(ml=it.current());++it)
QCString ci = letterToLabel((char)i);
if (charUsed[i].count()>0)
{ {
uint i = ml->letter();
QCString is = letterToLabel(i);
QCString ci = QString(QChar(i)).utf8();
QCString anchor; QCString anchor;
QCString extension=Doxygen::htmlFileExtension; QCString extension=Doxygen::htmlFileExtension;
if (!multiPage) if (!multiPage)
...@@ -2489,13 +2529,12 @@ static void writeQuickMemberIndex(OutputList &ol, ...@@ -2489,13 +2529,12 @@ static void writeQuickMemberIndex(OutputList &ol,
else if (first) else if (first)
anchor=fullName+extension+"#index_"; anchor=fullName+extension+"#index_";
else else
anchor=fullName+QCString().sprintf("_0x%02x",i)+extension+"#index_"; anchor=fullName+"_"+letterToLabel(i)+extension+"#index_";
startQuickIndexItem(ol,anchor+ci,i==page,TRUE,first); startQuickIndexItem(ol,anchor+ci,i==page,TRUE,first);
ol.writeString(is); ol.writeString(is);
endQuickIndexItem(ol); endQuickIndexItem(ol);
first=FALSE; first=FALSE;
} }
}
endQuickIndexList(ol); endQuickIndexList(ol);
} }
...@@ -2538,11 +2577,9 @@ static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight h ...@@ -2538,11 +2577,9 @@ static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight h
static bool disableIndex = Config_getBool("DISABLE_INDEX"); static bool disableIndex = Config_getBool("DISABLE_INDEX");
bool multiPageIndex=FALSE; bool multiPageIndex=FALSE;
int numPages=1;
if (documentedClassMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX) if (documentedClassMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
{ {
multiPageIndex=TRUE; multiPageIndex=TRUE;
numPages=127;
} }
ol.pushGeneratorState(); ol.pushGeneratorState();
...@@ -2561,22 +2598,20 @@ static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight h ...@@ -2561,22 +2598,20 @@ static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight h
if (multiPageIndex) Doxygen::indexList->incContentsDepth(); if (multiPageIndex) Doxygen::indexList->incContentsDepth();
} }
int page;
bool first=TRUE; bool first=TRUE;
for (page=0;page<numPages;page++) SIntDict<MemberIndexList>::Iterator it(g_memberIndexLetterUsed[hl]);
{ MemberIndexList *ml;
if (!multiPageIndex || g_memberIndexLetterUsed[hl][page].count()>0) for (it.toFirst();(ml=it.current());++it)
{ {
uint page = ml->letter();
QCString fileName = getCmhlInfo(hl)->fname; QCString fileName = getCmhlInfo(hl)->fname;
if (multiPageIndex) if (multiPageIndex)
{ {
if (!first) if (!first)
{ {
fileName+=QCString().sprintf("_0x%02x",page); fileName+="_"+letterToLabel(page);
} }
char cs[2]; QCString cs = QString(QChar(page)).utf8();
cs[0]=page;
cs[1]=0;
if (addToIndex) if (addToIndex)
{ {
Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE); Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
...@@ -2638,7 +2673,7 @@ static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight h ...@@ -2638,7 +2673,7 @@ static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight h
// normal lists otherwise // normal lists otherwise
ol.writeString("&#160;"); ol.writeString("&#160;");
} }
//ol.newParagraph(); // FIXME:PARA
writeMemberList(ol,quickIndex, writeMemberList(ol,quickIndex,
multiPageIndex?page:-1, multiPageIndex?page:-1,
g_memberIndexLetterUsed[hl], g_memberIndexLetterUsed[hl],
...@@ -2646,7 +2681,6 @@ static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight h ...@@ -2646,7 +2681,6 @@ static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight h
endFile(ol); endFile(ol);
first=FALSE; first=FALSE;
} }
}
if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth(); if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth();
...@@ -2716,11 +2750,9 @@ static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl) ...@@ -2716,11 +2750,9 @@ static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl)
static bool disableIndex = Config_getBool("DISABLE_INDEX"); static bool disableIndex = Config_getBool("DISABLE_INDEX");
bool multiPageIndex=FALSE; bool multiPageIndex=FALSE;
int numPages=1;
if (documentedFileMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX) if (documentedFileMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
{ {
multiPageIndex=TRUE; multiPageIndex=TRUE;
numPages=127;
} }
ol.pushGeneratorState(); ol.pushGeneratorState();
...@@ -2738,22 +2770,20 @@ static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl) ...@@ -2738,22 +2770,20 @@ static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl)
if (multiPageIndex) Doxygen::indexList->incContentsDepth(); if (multiPageIndex) Doxygen::indexList->incContentsDepth();
} }
int page;
bool first=TRUE; bool first=TRUE;
for (page=0;page<numPages;page++) SIntDict<MemberIndexList>::Iterator it(g_fileIndexLetterUsed[hl]);
{ MemberIndexList *ml;
if (!multiPageIndex || g_fileIndexLetterUsed[hl][page].count()>0) for (it.toFirst();(ml=it.current());++it)
{ {
uint page = ml->letter();
QCString fileName = getFmhlInfo(hl)->fname; QCString fileName = getFmhlInfo(hl)->fname;
if (multiPageIndex) if (multiPageIndex)
{ {
if (!first) if (!first)
{ {
fileName+=QCString().sprintf("_0x%02x",page); fileName+="_"+letterToLabel(page);
} }
char cs[2]; QCString cs = QString(QChar(page)).utf8();
cs[0]=page;
cs[1]=0;
if (addToIndex) if (addToIndex)
{ {
Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE); Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
...@@ -2813,8 +2843,7 @@ static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl) ...@@ -2813,8 +2843,7 @@ static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl)
// normal lists otherwise // normal lists otherwise
ol.writeString("&#160;"); ol.writeString("&#160;");
} }
//ol.newParagraph(); // FIXME:PARA
//writeFileMemberList(ol,quickIndex,hl,page);
writeMemberList(ol,quickIndex, writeMemberList(ol,quickIndex,
multiPageIndex?page:-1, multiPageIndex?page:-1,
g_fileIndexLetterUsed[hl], g_fileIndexLetterUsed[hl],
...@@ -2822,7 +2851,6 @@ static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl) ...@@ -2822,7 +2851,6 @@ static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl)
endFile(ol); endFile(ol);
first=FALSE; first=FALSE;
} }
}
if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth(); if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth();
ol.popGeneratorState(); ol.popGeneratorState();
} }
...@@ -2890,11 +2918,9 @@ static void writeNamespaceMemberIndexFiltered(OutputList &ol, ...@@ -2890,11 +2918,9 @@ static void writeNamespaceMemberIndexFiltered(OutputList &ol,
bool multiPageIndex=FALSE; bool multiPageIndex=FALSE;
int numPages=1;
if (documentedNamespaceMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX) if (documentedNamespaceMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
{ {
multiPageIndex=TRUE; multiPageIndex=TRUE;
numPages=127;
} }
ol.pushGeneratorState(); ol.pushGeneratorState();
...@@ -2912,22 +2938,20 @@ static void writeNamespaceMemberIndexFiltered(OutputList &ol, ...@@ -2912,22 +2938,20 @@ static void writeNamespaceMemberIndexFiltered(OutputList &ol,
if (multiPageIndex) Doxygen::indexList->incContentsDepth(); if (multiPageIndex) Doxygen::indexList->incContentsDepth();
} }
int page;
bool first=TRUE; bool first=TRUE;
for (page=0;page<numPages;page++) SIntDict<MemberIndexList>::Iterator it(g_namespaceIndexLetterUsed[hl]);
{ MemberIndexList *ml;
if (!multiPageIndex || g_namespaceIndexLetterUsed[hl][page].count()>0) for (it.toFirst();(ml=it.current());++it)
{ {
uint page = ml->letter();
QCString fileName = getNmhlInfo(hl)->fname; QCString fileName = getNmhlInfo(hl)->fname;
if (multiPageIndex) if (multiPageIndex)
{ {
if (!first) if (!first)
{ {
fileName+=QCString().sprintf("_0x%02x",page); fileName+="_"+letterToLabel(page);
} }
char cs[2]; QCString cs = QString(QChar(page)).utf8();
cs[0]=page;
cs[1]=0;
if (addToIndex) if (addToIndex)
{ {
Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE); Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
...@@ -2988,16 +3012,13 @@ static void writeNamespaceMemberIndexFiltered(OutputList &ol, ...@@ -2988,16 +3012,13 @@ static void writeNamespaceMemberIndexFiltered(OutputList &ol,
// normal lists otherwise // normal lists otherwise
ol.writeString("&#160;"); ol.writeString("&#160;");
} }
//ol.newParagraph(); // FIXME:PARA
//writeNamespaceMemberList(ol,quickIndex,hl,page);
writeMemberList(ol,quickIndex, writeMemberList(ol,quickIndex,
multiPageIndex?page:-1, multiPageIndex?page:-1,
g_namespaceIndexLetterUsed[hl], g_namespaceIndexLetterUsed[hl],
Definition::TypeNamespace); Definition::TypeNamespace);
endFile(ol); endFile(ol);
} }
}
if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth(); if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth();
ol.popGeneratorState(); ol.popGeneratorState();
} }
...@@ -3093,167 +3114,6 @@ static void writeExampleIndex(OutputList &ol) ...@@ -3093,167 +3114,6 @@ static void writeExampleIndex(OutputList &ol)
} }
//----------------------------------------------------------------------------
template<typename T>
bool writeMemberNavIndex(FTextStream &t,
int indent,
int n,
int documentedMembers[],
MemberIndexList indexLetterUsed[][MEMBER_INDEX_ENTRIES],
const T *(*getInfo)(int),
bool &first
)
{
bool found=FALSE;
QCString indentStr;
indentStr.fill(' ',indent*2);
// index items per category member lists
int i;
for (i=0;i<n;i++)
{
bool hasIndex = documentedMembers[i]>0;
bool quickIndex = documentedMembers[i]>maxItemsBeforeQuickIndex;
bool multiIndexPage = documentedMembers[i]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX;
if (hasIndex)
{
// terminate previous entry
if (!first) t << "," << endl;
first = FALSE;
// start entry
if (!found)
{
t << "[" << endl;
}
found = TRUE;
t << indentStr << " [ ";
t << "\"" << fixSpaces(getInfo(i)->title) << "\", ";
t << "\"" << getInfo(i)->fname << Doxygen::htmlFileExtension << "\", ";
bool firstPage=TRUE;
if (quickIndex)
{
t << "[ " << endl;
int j;
for (j=33;j<127;j++)
{
if (indexLetterUsed[i][j].count()>0)
{
if (!firstPage) t << "," << endl;
QCString fullName = getInfo(i)->fname;
QCString extension = Doxygen::htmlFileExtension;
QCString anchor;
if (firstPage || !multiIndexPage)
anchor=fullName+extension+"#index_";
else
anchor=fullName+QCString().sprintf("_0x%02x",j)+extension+"#index_";
char is[2];is[0]=(char)j;is[1]='\0';
QCString ci = letterToLabel((char)j);
t << indentStr << " [ ";
t << "\"" << is << "\", ";
t << "\"" << anchor << ci << "\", null ]";
firstPage=FALSE;
}
}
t << endl << indentStr << " ] ]";
}
else
{
t << "null" << " ]";
}
}
}
return found;
}
//----------------------------------------------------------------------------
#if 0
static bool writeFullNavIndex(FTextStream &t, LayoutNavEntry *root,int indent,bool &first)
{
static struct NavEntryCountMap
{
LayoutNavEntry::Kind kind;
bool hasItems;
} navEntryCountMap[] =
{
{ LayoutNavEntry::MainPage, TRUE },
{ LayoutNavEntry::Pages, indexedPages>0 },
{ LayoutNavEntry::Modules, documentedGroups>0 },
{ LayoutNavEntry::Namespaces, documentedNamespaces>0 },
{ LayoutNavEntry::NamespaceList, documentedNamespaces>0 },
{ LayoutNavEntry::NamespaceMembers, documentedNamespaceMembers[NMHL_All]>0 },
{ LayoutNavEntry::Classes, annotatedClasses>0 },
{ LayoutNavEntry::ClassList, annotatedClasses>0 },
{ LayoutNavEntry::ClassIndex, annotatedClasses>0 },
{ LayoutNavEntry::ClassHierarchy, hierarchyClasses>0 },
{ LayoutNavEntry::ClassMembers, documentedClassMembers[CMHL_All]>0 },
{ LayoutNavEntry::Files, documentedFiles>0 },
{ LayoutNavEntry::FileList, documentedFiles>0 },
{ LayoutNavEntry::FileGlobals, documentedFileMembers[FMHL_All]>0 },
//{ LayoutNavEntry::Dirs, documentedDirs>0 },
{ LayoutNavEntry::Examples, Doxygen::exampleSDict->count()>0 }
};
QCString indentStr;
indentStr.fill(' ',indent*2);
bool found=FALSE;
if (root->children().count()>0)
{
QListIterator<LayoutNavEntry> li(root->children());
LayoutNavEntry *entry;
for (li.toFirst();(entry=li.current());++li)
{
if (navEntryCountMap[entry->kind()].hasItems && entry->visible())
{
// terminate previous entry
if (!first) t << "," << endl;
first = FALSE;
// start entry
if (!found)
{
t << "[" << endl;
}
found = TRUE;
bool emptySection=TRUE;
t << indentStr << " [ ";
t << "\"" << fixSpaces(entry->title()) << "\", ";
t << "\"" << entry->baseFile() << Doxygen::htmlFileExtension << "\", ";
// write children (if any)
bool firstChild=TRUE;
if (entry->kind()==LayoutNavEntry::ClassMembers)
{
emptySection = !writeMemberNavIndex(t,indent+1,CMHL_Total,documentedClassMembers,g_memberIndexLetterUsed,&getCmhlInfo,firstChild);
}
else if (entry->kind()==LayoutNavEntry::NamespaceMembers)
{
emptySection = !writeMemberNavIndex(t,indent+1,NMHL_Total,documentedNamespaceMembers,g_namespaceIndexLetterUsed,&getNmhlInfo,firstChild);
}
else if (entry->kind()==LayoutNavEntry::FileGlobals)
{
emptySection = !writeMemberNavIndex(t,indent+1,FMHL_Total,documentedFileMembers,g_fileIndexLetterUsed,&getFmhlInfo,firstChild);
}
else
{
emptySection = !writeFullNavIndex(t,entry,indent+1,firstChild);
}
// end entry
if (emptySection) // entry without children
t << "null ]";
else // entry with children
t << endl << indentStr << " ] ]";
}
}
}
return found;
}
#endif
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static void countRelatedPages(int &docPages,int &indexPages) static void countRelatedPages(int &docPages,int &indexPages)
......
...@@ -5,7 +5,7 @@ function convertToId(search) ...@@ -5,7 +5,7 @@ function convertToId(search)
{ {
var c = search.charAt(i); var c = search.charAt(i);
var cn = c.charCodeAt(0); var cn = c.charCodeAt(0);
if (c.match(/[a-z0-9]/)) if (c.match(/[a-z0-9\u0080-\uFFFF]/))
{ {
result+=c; result+=c;
} }
...@@ -310,22 +310,20 @@ function SearchBox(name, resultsPath, inFrame, label) ...@@ -310,22 +310,20 @@ function SearchBox(name, resultsPath, inFrame, label)
var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); var searchValue = this.DOMSearchField().value.replace(/^ +/, "");
var code = searchValue.toLowerCase().charCodeAt(0); var code = searchValue.toLowerCase().charCodeAt(0);
var hexCode; var idxChar = searchValue.substr(0, 1).toLowerCase();
if (code<16) if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair
{ {
hexCode="0"+code.toString(16); idxChar = searchValue.substr(0, 2);
}
else
{
hexCode=code.toString(16);
} }
var resultsPage; var resultsPage;
var resultsPageWithSearch; var resultsPageWithSearch;
var hasResultsPage; var hasResultsPage;
if (indexSectionsWithContent[this.searchIndex].charAt(code) == '1') var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar);
if (idx!=-1)
{ {
var hexCode=idx.toString(16);
resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html';
resultsPageWithSearch = resultsPage+'?'+escape(searchValue); resultsPageWithSearch = resultsPage+'?'+escape(searchValue);
hasResultsPage = true; hasResultsPage = true;
......
...@@ -358,7 +358,7 @@ function main() ...@@ -358,7 +358,7 @@ function main()
$sorted = run_query($query); $sorted = run_query($query);
// Now output the HTML stuff... // Now output the HTML stuff...
// End the HTML form // End the HTML form
end_form(preg_replace("/[^a-zA-Z0-9\-\_\.]/i", " ", $query )); end_form(preg_replace("/[^a-zA-Z0-9\-\_\.\x80-\xFF]/i", " ", $query ));
// report results to the user // report results to the user
report_results($sorted); report_results($sorted);
end_page(); end_page();
......
...@@ -358,7 +358,7 @@ ...@@ -358,7 +358,7 @@
" $sorted = run_query($query);\n" " $sorted = run_query($query);\n"
" // Now output the HTML stuff...\n" " // Now output the HTML stuff...\n"
" // End the HTML form\n" " // End the HTML form\n"
" end_form(preg_replace(\"/[^a-zA-Z0-9\\-\\_\\.]/i\", \" \", $query ));\n" " end_form(preg_replace(\"/[^a-zA-Z0-9\\-\\_\\.\\x80-\\xFF]/i\", \" \", $query ));\n"
" // report results to the user\n" " // report results to the user\n"
" report_results($sorted);\n" " report_results($sorted);\n"
" end_page();\n" " end_page();\n"
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
" {\n" " {\n"
" var c = search.charAt(i);\n" " var c = search.charAt(i);\n"
" var cn = c.charCodeAt(0);\n" " var cn = c.charCodeAt(0);\n"
" if (c.match(/[a-z0-9]/))\n" " if (c.match(/[a-z0-9\\u0080-\\uFFFF]/))\n"
" {\n" " {\n"
" result+=c;\n" " result+=c;\n"
" }\n" " }\n"
...@@ -310,22 +310,20 @@ ...@@ -310,22 +310,20 @@
" var searchValue = this.DOMSearchField().value.replace(/^ +/, \"\");\n" " var searchValue = this.DOMSearchField().value.replace(/^ +/, \"\");\n"
"\n" "\n"
" var code = searchValue.toLowerCase().charCodeAt(0);\n" " var code = searchValue.toLowerCase().charCodeAt(0);\n"
" var hexCode;\n" " var idxChar = searchValue.substr(0, 1).toLowerCase();\n"
" if (code<16) \n" " if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair\n"
" {\n" " {\n"
" hexCode=\"0\"+code.toString(16);\n" " idxChar = searchValue.substr(0, 2);\n"
" }\n"
" else \n"
" {\n"
" hexCode=code.toString(16);\n"
" }\n" " }\n"
"\n" "\n"
" var resultsPage;\n" " var resultsPage;\n"
" var resultsPageWithSearch;\n" " var resultsPageWithSearch;\n"
" var hasResultsPage;\n" " var hasResultsPage;\n"
"\n" "\n"
" if (indexSectionsWithContent[this.searchIndex].charAt(code) == '1')\n" " var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar);\n"
" if (idx!=-1)\n"
" {\n" " {\n"
" var hexCode=idx.toString(16);\n"
" resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html';\n" " resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html';\n"
" resultsPageWithSearch = resultsPage+'?'+escape(searchValue);\n" " resultsPageWithSearch = resultsPage+'?'+escape(searchValue);\n"
" hasResultsPage = true;\n" " hasResultsPage = true;\n"
......
...@@ -587,8 +587,6 @@ static const char search_script[]= ...@@ -587,8 +587,6 @@ static const char search_script[]=
#include "search_js.h" #include "search_js.h"
; ;
#define MEMBER_INDEX_ENTRIES 256
#define SEARCH_INDEX_ALL 0 #define SEARCH_INDEX_ALL 0
#define SEARCH_INDEX_CLASSES 1 #define SEARCH_INDEX_CLASSES 1
#define SEARCH_INDEX_NAMESPACES 2 #define SEARCH_INDEX_NAMESPACES 2
...@@ -606,21 +604,31 @@ static const char search_script[]= ...@@ -606,21 +604,31 @@ static const char search_script[]=
#define SEARCH_INDEX_PAGES 14 #define SEARCH_INDEX_PAGES 14
#define NUM_SEARCH_INDICES 15 #define NUM_SEARCH_INDICES 15
class SearchIndexList : public SDict< QList<Definition> > class SearchDefinitionList : public QList<Definition>
{
public:
SearchDefinitionList(uint letter) : m_letter(letter) {}
uint letter() const { return m_letter; }
private:
uint m_letter;
};
class SearchIndexList : public SDict< SearchDefinitionList >
{ {
public: public:
SearchIndexList(int size=17) : SDict< QList<Definition> >(size,FALSE) typedef Definition ElementType;
SearchIndexList(uint letter) : SDict<SearchDefinitionList>(17,FALSE), m_letter(letter)
{ {
setAutoDelete(TRUE); setAutoDelete(TRUE);
} }
~SearchIndexList() {} ~SearchIndexList() {}
void append(Definition *d) void append(Definition *d)
{ {
QList<Definition> *l = find(d->name()); SearchDefinitionList *l = find(d->name());
if (l==0) if (l==0)
{ {
l=new QList<Definition>; l=new SearchDefinitionList(m_letter);
SDict< QList<Definition> >::append(d->name(),l); SDict<SearchDefinitionList>::append(d->name(),l);
} }
l->append(d); l->append(d);
} }
...@@ -632,10 +640,13 @@ class SearchIndexList : public SDict< QList<Definition> > ...@@ -632,10 +640,13 @@ class SearchIndexList : public SDict< QList<Definition> >
QCString n2 = md2->first()->localName(); QCString n2 = md2->first()->localName();
return qstricmp(n1.data(),n2.data()); return qstricmp(n1.data(),n2.data());
} }
uint letter() const { return m_letter; }
private:
uint m_letter;
}; };
static void addMemberToSearchIndex( static void addMemberToSearchIndex(
SearchIndexList symbols[NUM_SEARCH_INDICES][MEMBER_INDEX_ENTRIES], LetterToIndexMap<SearchIndexList> symbols[NUM_SEARCH_INDICES],
int symbolCount[NUM_SEARCH_INDICES], int symbolCount[NUM_SEARCH_INDICES],
MemberDef *md) MemberDef *md)
{ {
...@@ -653,58 +664,57 @@ static void addMemberToSearchIndex( ...@@ -653,58 +664,57 @@ static void addMemberToSearchIndex(
) )
{ {
QCString n = md->name(); QCString n = md->name();
uchar charCode = (uchar)n.at(0);
uint letter = charCode<128 ? tolower(charCode) : charCode;
if (!n.isEmpty()) if (!n.isEmpty())
{ {
uint letter = getUtf8CodeToLower(n,0);
bool isFriendToHide = hideFriendCompounds && bool isFriendToHide = hideFriendCompounds &&
(QCString(md->typeString())=="friend class" || (QCString(md->typeString())=="friend class" ||
QCString(md->typeString())=="friend struct" || QCString(md->typeString())=="friend struct" ||
QCString(md->typeString())=="friend union"); QCString(md->typeString())=="friend union");
if (!(md->isFriend() && isFriendToHide)) if (!(md->isFriend() && isFriendToHide))
{ {
symbols[SEARCH_INDEX_ALL][letter].append(md); symbols[SEARCH_INDEX_ALL].append(letter,md);
symbolCount[SEARCH_INDEX_ALL]++; symbolCount[SEARCH_INDEX_ALL]++;
} }
if (md->isFunction() || md->isSlot() || md->isSignal()) if (md->isFunction() || md->isSlot() || md->isSignal())
{ {
symbols[SEARCH_INDEX_FUNCTIONS][letter].append(md); symbols[SEARCH_INDEX_FUNCTIONS].append(letter,md);
symbolCount[SEARCH_INDEX_FUNCTIONS]++; symbolCount[SEARCH_INDEX_FUNCTIONS]++;
} }
else if (md->isVariable()) else if (md->isVariable())
{ {
symbols[SEARCH_INDEX_VARIABLES][letter].append(md); symbols[SEARCH_INDEX_VARIABLES].append(letter,md);
symbolCount[SEARCH_INDEX_VARIABLES]++; symbolCount[SEARCH_INDEX_VARIABLES]++;
} }
else if (md->isTypedef()) else if (md->isTypedef())
{ {
symbols[SEARCH_INDEX_TYPEDEFS][letter].append(md); symbols[SEARCH_INDEX_TYPEDEFS].append(letter,md);
symbolCount[SEARCH_INDEX_TYPEDEFS]++; symbolCount[SEARCH_INDEX_TYPEDEFS]++;
} }
else if (md->isEnumerate()) else if (md->isEnumerate())
{ {
symbols[SEARCH_INDEX_ENUMS][letter].append(md); symbols[SEARCH_INDEX_ENUMS].append(letter,md);
symbolCount[SEARCH_INDEX_ENUMS]++; symbolCount[SEARCH_INDEX_ENUMS]++;
} }
else if (md->isEnumValue()) else if (md->isEnumValue())
{ {
symbols[SEARCH_INDEX_ENUMVALUES][letter].append(md); symbols[SEARCH_INDEX_ENUMVALUES].append(letter,md);
symbolCount[SEARCH_INDEX_ENUMVALUES]++; symbolCount[SEARCH_INDEX_ENUMVALUES]++;
} }
else if (md->isProperty()) else if (md->isProperty())
{ {
symbols[SEARCH_INDEX_PROPERTIES][letter].append(md); symbols[SEARCH_INDEX_PROPERTIES].append(letter,md);
symbolCount[SEARCH_INDEX_PROPERTIES]++; symbolCount[SEARCH_INDEX_PROPERTIES]++;
} }
else if (md->isEvent()) else if (md->isEvent())
{ {
symbols[SEARCH_INDEX_EVENTS][letter].append(md); symbols[SEARCH_INDEX_EVENTS].append(letter,md);
symbolCount[SEARCH_INDEX_EVENTS]++; symbolCount[SEARCH_INDEX_EVENTS]++;
} }
else if (md->isRelated() || md->isForeign() || else if (md->isRelated() || md->isForeign() ||
(md->isFriend() && !isFriendToHide)) (md->isFriend() && !isFriendToHide))
{ {
symbols[SEARCH_INDEX_RELATED][letter].append(md); symbols[SEARCH_INDEX_RELATED].append(letter,md);
symbolCount[SEARCH_INDEX_RELATED]++; symbolCount[SEARCH_INDEX_RELATED]++;
} }
} }
...@@ -716,47 +726,48 @@ static void addMemberToSearchIndex( ...@@ -716,47 +726,48 @@ static void addMemberToSearchIndex(
) )
{ {
QCString n = md->name(); QCString n = md->name();
uchar charCode = (uchar)n.at(0);
uint letter = charCode<128 ? tolower(charCode) : charCode;
if (!n.isEmpty()) if (!n.isEmpty())
{ {
symbols[SEARCH_INDEX_ALL][letter].append(md); uint letter = getUtf8CodeToLower(n,0);
symbols[SEARCH_INDEX_ALL].append(letter,md);
symbolCount[SEARCH_INDEX_ALL]++; symbolCount[SEARCH_INDEX_ALL]++;
if (md->isFunction()) if (md->isFunction())
{ {
symbols[SEARCH_INDEX_FUNCTIONS][letter].append(md); symbols[SEARCH_INDEX_FUNCTIONS].append(letter,md);
symbolCount[SEARCH_INDEX_FUNCTIONS]++; symbolCount[SEARCH_INDEX_FUNCTIONS]++;
} }
else if (md->isVariable()) else if (md->isVariable())
{ {
symbols[SEARCH_INDEX_VARIABLES][letter].append(md); symbols[SEARCH_INDEX_VARIABLES].append(letter,md);
symbolCount[SEARCH_INDEX_VARIABLES]++; symbolCount[SEARCH_INDEX_VARIABLES]++;
} }
else if (md->isTypedef()) else if (md->isTypedef())
{ {
symbols[SEARCH_INDEX_TYPEDEFS][letter].append(md); symbols[SEARCH_INDEX_TYPEDEFS].append(letter,md);
symbolCount[SEARCH_INDEX_TYPEDEFS]++; symbolCount[SEARCH_INDEX_TYPEDEFS]++;
} }
else if (md->isEnumerate()) else if (md->isEnumerate())
{ {
symbols[SEARCH_INDEX_ENUMS][letter].append(md); symbols[SEARCH_INDEX_ENUMS].append(letter,md);
symbolCount[SEARCH_INDEX_ENUMS]++; symbolCount[SEARCH_INDEX_ENUMS]++;
} }
else if (md->isEnumValue()) else if (md->isEnumValue())
{ {
symbols[SEARCH_INDEX_ENUMVALUES][letter].append(md); symbols[SEARCH_INDEX_ENUMVALUES].append(letter,md);
symbolCount[SEARCH_INDEX_ENUMVALUES]++; symbolCount[SEARCH_INDEX_ENUMVALUES]++;
} }
else if (md->isDefine()) else if (md->isDefine())
{ {
symbols[SEARCH_INDEX_DEFINES][letter].append(md); symbols[SEARCH_INDEX_DEFINES].append(letter,md);
symbolCount[SEARCH_INDEX_DEFINES]++; symbolCount[SEARCH_INDEX_DEFINES]++;
} }
} }
} }
} }
// see also function convertToId() in search.js, which should match in
// behaviour
static QCString searchId(const QCString &s) static QCString searchId(const QCString &s)
{ {
int c; int c;
...@@ -765,11 +776,15 @@ static QCString searchId(const QCString &s) ...@@ -765,11 +776,15 @@ static QCString searchId(const QCString &s)
for (i=0;i<s.length();i++) for (i=0;i<s.length();i++)
{ {
c=s.at(i); c=s.at(i);
if ((c>='0' && c<='9') || (c>='A' && c<='Z') || (c>='a' && c<='z')) if (c>0x7f || c<0) // part of multibyte character
{
result+=(char)c;
}
else if (isalnum(c)) // simply alpha numerical character
{ {
result+=(char)tolower(c); result+=(char)tolower(c);
} }
else else // other 'unprintable' characters
{ {
char val[4]; char val[4];
sprintf(val,"_%02x",(uchar)c); sprintf(val,"_%02x",(uchar)c);
...@@ -780,7 +795,7 @@ static QCString searchId(const QCString &s) ...@@ -780,7 +795,7 @@ static QCString searchId(const QCString &s)
} }
static int g_searchIndexCount[NUM_SEARCH_INDICES]; static int g_searchIndexCount[NUM_SEARCH_INDICES];
static SearchIndexList g_searchIndexSymbols[NUM_SEARCH_INDICES][MEMBER_INDEX_ENTRIES]; static LetterToIndexMap<SearchIndexList> g_searchIndexSymbols[NUM_SEARCH_INDICES];
static const char *g_searchIndexName[NUM_SEARCH_INDICES] = static const char *g_searchIndexName[NUM_SEARCH_INDICES] =
{ {
"all", "all",
...@@ -834,12 +849,11 @@ void writeJavascriptSearchIndex() ...@@ -834,12 +849,11 @@ void writeJavascriptSearchIndex()
ClassDef *cd; ClassDef *cd;
for (;(cd=cli.current());++cli) for (;(cd=cli.current());++cli)
{ {
uchar charCode = (uchar)cd->localName().at(0); uint letter = getUtf8CodeToLower(cd->localName(),0);
uint letter = charCode<128 ? tolower(charCode) : charCode;
if (cd->isLinkable() && isId(letter)) if (cd->isLinkable() && isId(letter))
{ {
g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(cd); g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,cd);
g_searchIndexSymbols[SEARCH_INDEX_CLASSES][letter].append(cd); g_searchIndexSymbols[SEARCH_INDEX_CLASSES].append(letter,cd);
g_searchIndexCount[SEARCH_INDEX_ALL]++; g_searchIndexCount[SEARCH_INDEX_ALL]++;
g_searchIndexCount[SEARCH_INDEX_CLASSES]++; g_searchIndexCount[SEARCH_INDEX_CLASSES]++;
} }
...@@ -850,12 +864,11 @@ void writeJavascriptSearchIndex() ...@@ -850,12 +864,11 @@ void writeJavascriptSearchIndex()
NamespaceDef *nd; NamespaceDef *nd;
for (;(nd=nli.current());++nli) for (;(nd=nli.current());++nli)
{ {
uchar charCode = (uchar)nd->name().at(0); uint letter = getUtf8CodeToLower(nd->name(),0);
uint letter = charCode<128 ? tolower(charCode) : charCode;
if (nd->isLinkable() && isId(letter)) if (nd->isLinkable() && isId(letter))
{ {
g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(nd); g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,nd);
g_searchIndexSymbols[SEARCH_INDEX_NAMESPACES][letter].append(nd); g_searchIndexSymbols[SEARCH_INDEX_NAMESPACES].append(letter,nd);
g_searchIndexCount[SEARCH_INDEX_ALL]++; g_searchIndexCount[SEARCH_INDEX_ALL]++;
g_searchIndexCount[SEARCH_INDEX_NAMESPACES]++; g_searchIndexCount[SEARCH_INDEX_NAMESPACES]++;
} }
...@@ -870,12 +883,11 @@ void writeJavascriptSearchIndex() ...@@ -870,12 +883,11 @@ void writeJavascriptSearchIndex()
FileDef *fd; FileDef *fd;
for (;(fd=fni.current());++fni) for (;(fd=fni.current());++fni)
{ {
uchar charCode = (uchar)fd->name().at(0); uint letter = getUtf8CodeToLower(fd->name(),0);
uint letter = charCode<128 ? tolower(charCode) : charCode;
if (fd->isLinkable() && isId(letter)) if (fd->isLinkable() && isId(letter))
{ {
g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(fd); g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,fd);
g_searchIndexSymbols[SEARCH_INDEX_FILES][letter].append(fd); g_searchIndexSymbols[SEARCH_INDEX_FILES].append(letter,fd);
g_searchIndexCount[SEARCH_INDEX_ALL]++; g_searchIndexCount[SEARCH_INDEX_ALL]++;
g_searchIndexCount[SEARCH_INDEX_FILES]++; g_searchIndexCount[SEARCH_INDEX_FILES]++;
} }
...@@ -930,8 +942,8 @@ void writeJavascriptSearchIndex() ...@@ -930,8 +942,8 @@ void writeJavascriptSearchIndex()
uint letter = charCode<128 ? tolower(charCode) : charCode; uint letter = charCode<128 ? tolower(charCode) : charCode;
if (isId(letter)) if (isId(letter))
{ {
g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(gd); g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,gd);
g_searchIndexSymbols[SEARCH_INDEX_GROUPS][letter].append(gd); g_searchIndexSymbols[SEARCH_INDEX_GROUPS].append(letter,gd);
g_searchIndexCount[SEARCH_INDEX_ALL]++; g_searchIndexCount[SEARCH_INDEX_ALL]++;
g_searchIndexCount[SEARCH_INDEX_GROUPS]++; g_searchIndexCount[SEARCH_INDEX_GROUPS]++;
} }
...@@ -953,8 +965,8 @@ void writeJavascriptSearchIndex() ...@@ -953,8 +965,8 @@ void writeJavascriptSearchIndex()
uint letter = charCode<128 ? tolower(charCode) : charCode; uint letter = charCode<128 ? tolower(charCode) : charCode;
if (isId(letter)) if (isId(letter))
{ {
g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(pd); g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,pd);
g_searchIndexSymbols[SEARCH_INDEX_PAGES][letter].append(pd); g_searchIndexSymbols[SEARCH_INDEX_PAGES].append(letter,pd);
g_searchIndexCount[SEARCH_INDEX_ALL]++; g_searchIndexCount[SEARCH_INDEX_ALL]++;
g_searchIndexCount[SEARCH_INDEX_PAGES]++; g_searchIndexCount[SEARCH_INDEX_PAGES]++;
} }
...@@ -970,8 +982,8 @@ void writeJavascriptSearchIndex() ...@@ -970,8 +982,8 @@ void writeJavascriptSearchIndex()
uint letter = charCode<128 ? tolower(charCode) : charCode; uint letter = charCode<128 ? tolower(charCode) : charCode;
if (isId(letter)) if (isId(letter))
{ {
g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(Doxygen::mainPage); g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,Doxygen::mainPage);
g_searchIndexSymbols[SEARCH_INDEX_PAGES][letter].append(Doxygen::mainPage); g_searchIndexSymbols[SEARCH_INDEX_PAGES].append(letter,Doxygen::mainPage);
g_searchIndexCount[SEARCH_INDEX_ALL]++; g_searchIndexCount[SEARCH_INDEX_ALL]++;
g_searchIndexCount[SEARCH_INDEX_PAGES]++; g_searchIndexCount[SEARCH_INDEX_PAGES]++;
} }
...@@ -979,29 +991,29 @@ void writeJavascriptSearchIndex() ...@@ -979,29 +991,29 @@ void writeJavascriptSearchIndex()
} }
// sort all lists // sort all lists
int i,p; int i;
for (i=0;i<NUM_SEARCH_INDICES;i++) for (i=0;i<NUM_SEARCH_INDICES;i++)
{ {
for (p=0;p<MEMBER_INDEX_ENTRIES;p++) SIntDict<SearchIndexList>::Iterator it(g_searchIndexSymbols[i]);
{ SearchIndexList *sl;
if (g_searchIndexSymbols[i][p].count()>0) for (it.toFirst();(sl=it.current());++it)
{ {
g_searchIndexSymbols[i][p].sort(); sl->sort();
}
} }
} }
// write index files // write index files
QCString searchDirName = Config_getString("HTML_OUTPUT")+"/search"; QCString searchDirName = Config_getString("HTML_OUTPUT")+"/search";
for (i=0;i<NUM_SEARCH_INDICES;i++) for (i=0;i<NUM_SEARCH_INDICES;i++) // for each index
{
for (p=0;p<MEMBER_INDEX_ENTRIES;p++)
{ {
if (g_searchIndexSymbols[i][p].count()>0) SIntDict<SearchIndexList>::Iterator it(g_searchIndexSymbols[i]);
SearchIndexList *sl;
int p=0;
for (it.toFirst();(sl=it.current());++it,++p) // for each letter
{ {
QCString baseName; QCString baseName;
baseName.sprintf("%s_%02x",g_searchIndexName[i],p); baseName.sprintf("%s_%x",g_searchIndexName[i],p);
QCString fileName = searchDirName + "/"+baseName+".html"; QCString fileName = searchDirName + "/"+baseName+".html";
QCString dataFileName = searchDirName + "/"+baseName+".js"; QCString dataFileName = searchDirName + "/"+baseName+".js";
...@@ -1060,8 +1072,8 @@ void writeJavascriptSearchIndex() ...@@ -1060,8 +1072,8 @@ void writeJavascriptSearchIndex()
ti << "[" << endl; ti << "[" << endl;
bool firstEntry=TRUE; bool firstEntry=TRUE;
SDict<QList<Definition> >::Iterator li(g_searchIndexSymbols[i][p]); SDict<SearchDefinitionList>::Iterator li(*sl);
QList<Definition> *dl; SearchDefinitionList *dl;
int itemCount=0; int itemCount=0;
for (li.toFirst();(dl=li.current());++li) for (li.toFirst();(dl=li.current());++li)
{ {
...@@ -1253,7 +1265,6 @@ void writeJavascriptSearchIndex() ...@@ -1253,7 +1265,6 @@ void writeJavascriptSearchIndex()
} }
} }
} }
}
{ {
QFile f(searchDirName+"/search.js"); QFile f(searchDirName+"/search.js");
...@@ -1275,9 +1286,12 @@ void writeJavascriptSearchIndex() ...@@ -1275,9 +1286,12 @@ void writeJavascriptSearchIndex()
{ {
if (!first) t << "," << endl; if (!first) t << "," << endl;
t << " " << j << ": \""; t << " " << j << ": \"";
for (p=0;p<MEMBER_INDEX_ENTRIES;p++)
SIntDict<SearchIndexList>::Iterator it(g_searchIndexSymbols[i]);
SearchIndexList *sl;
for (it.toFirst();(sl=it.current());++it) // for each letter
{ {
t << (g_searchIndexSymbols[i][p].count()>0 ? "1" : "0"); t << QString( QChar( sl->letter() ) ).utf8();
} }
t << "\""; t << "\"";
first=FALSE; first=FALSE;
......
...@@ -108,7 +108,7 @@ class SDict ...@@ -108,7 +108,7 @@ class SDict
* \param caseSensitive indicated whether the keys should be sorted * \param caseSensitive indicated whether the keys should be sorted
* in a case sensitive way. * in a case sensitive way.
*/ */
SDict(int size,bool caseSensitive=TRUE) : m_sizeIndex(0) SDict(int size=17,bool caseSensitive=TRUE) : m_sizeIndex(0)
{ {
m_list = new SList<T>(this); m_list = new SList<T>(this);
#if AUTORESIZE #if AUTORESIZE
...@@ -454,7 +454,7 @@ class SIntDict ...@@ -454,7 +454,7 @@ class SIntDict
* \param size The size of the dictionary. Should be a prime number for * \param size The size of the dictionary. Should be a prime number for
* best distribution of elements. * best distribution of elements.
*/ */
SIntDict(int size) : m_sizeIndex(0) SIntDict(int size=17) : m_sizeIndex(0)
{ {
m_list = new SIntList<T>(this); m_list = new SIntList<T>(this);
#if AUTORESIZE #if AUTORESIZE
...@@ -659,6 +659,76 @@ class SIntDict ...@@ -659,6 +659,76 @@ class SIntDict
QListIterator<T> *m_li; QListIterator<T> *m_li;
}; };
class IteratorDict; // first forward declare
friend class IteratorDict; // then make it a friend
/*! Simple iterator for SDict. It iterates over the dictionary elements
* in an unsorted way, but does provide information about the element's key.
*/
class IteratorDict
{
public:
/*! Create an iterator given the dictionary. */
IteratorDict(const SIntDict<T> &dict)
{
m_di = new QIntDictIterator<T>(*dict.m_dict);
}
/*! Destroys the dictionary */
virtual ~IteratorDict()
{
delete m_di;
}
/*! Set the iterator to the first element in the list.
* \return The first compound, or zero if the list was empty.
*/
T *toFirst() const
{
return m_di->toFirst();
}
/*! Set the iterator to the last element in the list.
* \return The first compound, or zero if the list was empty.
*/
T *toLast() const
{
return m_di->toLast();
}
/*! Returns the current compound */
T *current() const
{
return m_di->current();
}
/*! Returns the current key */
int currentKey() const
{
return m_di->currentKey();
}
/*! Moves the iterator to the next element.
* \return the new "current" element, or zero if the iterator was
* already pointing at the last element.
*/
T *operator++()
{
return m_di->operator++();
}
/*! Moves the iterator to the previous element.
* \return the new "current" element, or zero if the iterator was
* already pointing at the first element.
*/
T *operator--()
{
return m_di->operator--();
}
private:
QDictIterator<T> *m_di;
};
}; };
#endif #endif
...@@ -7919,3 +7919,72 @@ void addDocCrossReference(MemberDef *src,MemberDef *dst) ...@@ -7919,3 +7919,72 @@ void addDocCrossReference(MemberDef *src,MemberDef *dst)
} }
} }
//--------------------------------------------------------------------------------------
/*! @brief Get one unicode character as an unsigned integer from utf-8 string
*
* @param s utf-8 encoded string
* @param idx byte position of given string \a s.
* @return the unicode codepoint, 0 - MAX_UNICODE_CODEPOINT
* @see getNextUtf8OrToLower()
* @see getNextUtf8OrToUpper()
*/
uint getUtf8Code( const QCString& s, int idx )
{
const int length = s.length();
if (idx >= length) { return 0; }
const uint c0 = (uchar)s.at(idx);
if ( c0 < 0xC2 || c0 >= 0xF8 ) // 1 byte character
{
return c0;
}
if (idx+1 >= length) { return 0; }
const uint c1 = ((uchar)s.at(idx+1)) & 0x3f;
if ( c0 < 0xE0 ) // 2 byte character
{
return ((c0 & 0x1f) << 6) | c1;
}
if (idx+2 >= length) { return 0; }
const uint c2 = ((uchar)s.at(idx+2)) & 0x3f;
if ( c0 < 0xF0 ) // 3 byte character
{
return ((c0 & 0x0f) << 12) | (c1 << 6) | c2;
}
if (idx+3 >= length) { return 0; }
// 4 byte character
const uint c3 = ((uchar)s.at(idx+3)) & 0x3f;
return ((c0 & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3;
}
/*! @brief Returns one unicode character as an unsigned integer
* from utf-8 string, making the character lower case if it was upper case.
*
* @param s utf-8 encoded string
* @param idx byte position of given string \a s.
* @return the unicode codepoint, 0 - MAX_UNICODE_CODEPOINT, excludes 'A'-'Z'
* @see getNextUtf8Code()
*/
uint getUtf8CodeToLower( const QCString& s, int idx )
{
const uint v = getUtf8Code( s, idx );
return v < 0x7f ? tolower( v ) : v;
}
/*! @brief Returns one unicode character as ian unsigned interger
* from utf-8 string, making the character upper case if it was lower case.
*
* @param s utf-8 encoded string
* @param idx byte position of given string \a s.
* @return the unicode codepoint, 0 - MAX_UNICODE_CODEPOINT, excludes 'A'-'Z'
* @see getNextUtf8Code()
*/
uint getUtf8CodeToUpper( const QCString& s, int idx )
{
const uint v = getUtf8Code( s, idx );
return v < 0x7f ? toupper( v ) : v;
}
//--------------------------------------------------------------------------------------
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <qlist.h> #include <qlist.h>
#include <ctype.h> #include <ctype.h>
#include "types.h" #include "types.h"
#include "sortdict.h"
//-------------------------------------------------------------------- //--------------------------------------------------------------------
...@@ -87,6 +88,33 @@ class TextGeneratorOLImpl : public TextGeneratorIntf ...@@ -87,6 +88,33 @@ class TextGeneratorOLImpl : public TextGeneratorIntf
//-------------------------------------------------------------------- //--------------------------------------------------------------------
/** @brief maps a unicode character code to a list of T::ElementType's
*/
template<class T>
class LetterToIndexMap : public SIntDict<T>
{
public:
LetterToIndexMap() { SIntDict<T>::setAutoDelete(TRUE); }
int compareItems(QCollection::Item item1, QCollection::Item item2)
{
T *l1=(T *)item1;
T *l2=(T *)item2;
return (int)l1->letter()-(int)l2->letter();
}
void append(uint letter,typename T::ElementType *elem)
{
T *l = SIntDict<T>::find((int)letter);
if (l==0)
{
l = new T(letter);
SIntDict<T>::inSort((int)letter,l);
}
l->append(elem);
}
};
//--------------------------------------------------------------------
QCString langToString(SrcLangExt lang); QCString langToString(SrcLangExt lang);
QCString getLanguageSpecificSeparator(SrcLangExt lang,bool classScope=FALSE); QCString getLanguageSpecificSeparator(SrcLangExt lang,bool classScope=FALSE);
...@@ -411,5 +439,9 @@ bool fileVisibleInIndex(FileDef *fd,bool &genSourceFile); ...@@ -411,5 +439,9 @@ bool fileVisibleInIndex(FileDef *fd,bool &genSourceFile);
void addDocCrossReference(MemberDef *src,MemberDef *dst); void addDocCrossReference(MemberDef *src,MemberDef *dst);
uint getUtf8Code( const QCString& s, int idx );
uint getUtf8CodeToLower( const QCString& s, int idx );
uint getUtf8CodeToUpper( const QCString& s, int idx );
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment