From bca6baee6685b489c36abec5a3b550921294e228 Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Sat, 14 Sep 2013 17:11:20 +0200 Subject: Bug 705910 - Indexing and searching cannot treat non ASCII identifiers --- qtools/Doxyfile | 2 +- src/index.cpp | 906 +++++++++++++++++++-------------------------- src/search.js | 16 +- src/search_functions.php | 2 +- src/search_functions_php.h | 2 +- src/search_js.h | 16 +- src/searchindex.cpp | 530 +++++++++++++------------- src/sortdict.h | 76 +++- src/util.cpp | 69 ++++ src/util.h | 32 ++ 10 files changed, 846 insertions(+), 805 deletions(-) diff --git a/qtools/Doxyfile b/qtools/Doxyfile index 9b5af64..fee2bd5 100644 --- a/qtools/Doxyfile +++ b/qtools/Doxyfile @@ -174,7 +174,7 @@ QHP_SECT_FILTER_ATTRS = QHG_LOCATION = GENERATE_ECLIPSEHELP = YES ECLIPSE_DOC_ID = org.doxygen.qtools -DISABLE_INDEX = YES +DISABLE_INDEX = NO GENERATE_TREEVIEW = YES ENUM_VALUES_PER_LINE = 4 TREEVIEW_WIDTH = 250 diff --git a/src/index.cpp b/src/index.cpp index 5970a43..5e9ed36 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -119,23 +119,28 @@ static void endIndexHierarchy(OutputList &ol,int level) class MemberIndexList : public QList { public: - MemberIndexList() : QList() {} + typedef MemberDef ElementType; + MemberIndexList(uint letter) : QList(), m_letter(letter) {} ~MemberIndexList() {} int compareItems(QCollection::Item item1, QCollection::Item item2) { MemberDef *md1=(MemberDef *)item1; 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 MemberIndexList g_memberIndexLetterUsed[CMHL_Total][MEMBER_INDEX_ENTRIES]; -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]; +static LetterToIndexMap g_memberIndexLetterUsed[CMHL_Total]; +static LetterToIndexMap g_fileIndexLetterUsed[FMHL_Total]; +static LetterToIndexMap g_namespaceIndexLetterUsed[NMHL_Total]; const int maxItemsBeforeQuickIndex = MAX_ITEMS_BEFORE_QUICK_INDEX; @@ -1690,21 +1695,39 @@ static void writeAnnotatedClassList(OutputList &ol) ol.endIndexList(); } -static QCString letterToLabel(char startLetter) +static QCString letterToLabel(uint startLetter) { - QCString s(5); - if (isId(startLetter)) + char s[10]; + if (startLetter>0x20 && startLetter<=0x7f) // printable ASCII character { - s[0]=startLetter; s[1]=0; + s[0]=(char)startLetter; + s[1]=0; } else { const char hex[]="0123456789abcdef"; - s[0]='0'; - s[1]='x'; - s[2]=hex[startLetter>>4]; - s[3]=hex[startLetter&0xF]; - s[4]=0; + int i=0; + s[i++]='0'; + s[i++]='x'; + if (startLetter>(1<<24)) // 4 byte character + { + 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; } @@ -1714,35 +1737,40 @@ static QCString letterToLabel(char startLetter) /** Special class list where sorting takes IGNORE_PREFIX into account. */ class PrefixIgnoreClassList : public ClassList { -public: - virtual int compareItems(QCollection::Item item1, QCollection::Item item2) - { - ClassDef *c1=(ClassDef *)item1; - ClassDef *c2=(ClassDef *)item2; + public: + typedef ClassDef ElementType; + PrefixIgnoreClassList(uint letter) : m_letter(letter) {} + virtual int compareItems(QCollection::Item item1, QCollection::Item item2) + { + ClassDef *c1=(ClassDef *)item1; + ClassDef *c2=(ClassDef *)item2; - QCString n1 = c1->className(); - QCString n2 = c2->className(); - return qstricmp (n1.data()+getPrefixIndex(n1), n2.data()+getPrefixIndex(n2)); - } + QCString n1 = c1->className(); + QCString n2 = c2->className(); + 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 AlphaIndexTableCell { 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) { //printf("AlphaIndexTableCell(%d,%d,%c,%s)\n",row,col,letter!=0 ? letter: '-', // cd!=(ClassDef*)0x8 ? cd->name().data() : ""); } 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 column() const { return m_col; } private: - uchar m_letter; + uint m_letter; ClassDef *m_class; int m_row; int m_col; @@ -1770,12 +1798,31 @@ class AlphaIndexTableColumns : public QList AlphaIndexTableColumns() { setAutoDelete(TRUE); } }; +class UsedIndexLetters : public SIntDict +{ + public: + UsedIndexLetters() : SIntDict(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 static void writeAlphabeticalClassList(OutputList &ol) { // What starting letters are used - bool indexLetterUsed[256]; - memset (indexLetterUsed, 0, sizeof (indexLetterUsed)); + UsedIndexLetters indexLettersUsed; // first count the number of headers ClassSDict::Iterator cli(*Doxygen::classSDict); @@ -1791,24 +1838,25 @@ static void writeAlphabeticalClassList(OutputList &ol) int index = getPrefixIndex(cd->className()); //printf("name=%s index=%d %d\n",cd->className().data(),index,cd->protection()); - startLetter=toupper(cd->className().at(index))&0xFF; - indexLetterUsed[startLetter] = true; + startLetter=getUtf8CodeToUpper(cd->className(),index); + indexLettersUsed.add(startLetter); } } + indexLettersUsed.sort(); // write quick link index (row of letters) QCString alphaLinks = "
"; - int l; - for (l=0; l<256; l++) - { - if (indexLetterUsed[l]) - { - if (headerItems) alphaLinks += " | "; - headerItems++; - alphaLinks += (QCString)"" + - (char)l + ""; - } + SIntDict::Iterator it(indexLettersUsed); + uint *pLetter; + for (it.toFirst();(pLetter=it.current());++it) + { + if (headerItems) alphaLinks += " | "; + headerItems++; + QCString li = letterToLabel(*pLetter); + QCString ls = QString(QChar(*pLetter)).utf8(); + alphaLinks += (QCString)"" + + ls + ""; } alphaLinks += "
\n"; ol.writeString(alphaLinks); @@ -1825,7 +1873,7 @@ static void writeAlphabeticalClassList(OutputList &ol) // headerItems,totalItems,columns,rows,itemsInLastRow); // Keep a list of classes for each starting letter - PrefixIgnoreClassList classesByLetter[256]; + LetterToIndexMap classesByLetter; AlphaIndexTableColumns tableColumns; // fill the columns with the class list (row elements in each column, @@ -1841,16 +1889,20 @@ static void writeAlphabeticalClassList(OutputList &ol) if (cd->isLinkableInProject() && cd->templateMaster()==0) { 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 // prefix, which should be ignored really. if (cd->getLanguage()==SrcLangExt_VHDL) { if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS )// no architecture - classesByLetter[startLetter].inSort(cd); + { + classesByLetter.append(startLetter,cd); + } } else - classesByLetter[startLetter].inSort(cd); + { + classesByLetter.append(startLetter,cd); + } } } @@ -1871,25 +1923,29 @@ static void writeAlphabeticalClassList(OutputList &ol) AlphaIndexTableRows *tableRows = new AlphaIndexTableRows; tableColumns.append(tableRows); int col=0,row=0,maxRows=0; - for (l=0; l<256; l++) - { - if (classesByLetter[l].count()>0) + PrefixIgnoreClassList *cl; + SIntDict::Iterator lit(classesByLetter); + for (lit.toFirst();(cl=lit.current());++lit) + { + uint l = cl->letter(); + // add special header cell + tableRows->append(new AlphaIndexTableCell(row,col,l,(ClassDef*)0x8)); + row++; + tableRows->append(new AlphaIndexTableCell(row,col,0,(ClassDef*)0x8)); + row++; + ClassListIterator cit(*cl); + cit.toFirst(); + ClassDef *cd = cit.current(); + ++cit; + tableRows->append(new AlphaIndexTableCell(row,col,0,cd)); + row++; + NEXT_ROW(); + for (;(cd=cit.current()); ++cit) { - // add special header cell - tableRows->append(new AlphaIndexTableCell(row,col,(uchar)l,(ClassDef*)0x8)); - row++; - tableRows->append(new AlphaIndexTableCell(row,col,0,(ClassDef*)0x8)); + // add normal cell + tableRows->append(new AlphaIndexTableCell(row,col,0,cd)); row++; - tableRows->append(new AlphaIndexTableCell(row,col,0,classesByLetter[l].at(0))); - row++; NEXT_ROW(); - for (i=1; i<(int)classesByLetter[l].count(); i++) - { - // add normal cell - tableRows->append(new AlphaIndexTableCell(row,col,0,classesByLetter[l].at(i))); - row++; - NEXT_ROW(); - } } } @@ -1936,7 +1992,7 @@ static void writeAlphabeticalClassList(OutputList &ol) ol.writeString("" "" "" "" @@ -2164,14 +2220,9 @@ static void writeNamespaceLinkForMember(OutputList &ol,MemberDef *md,const char } static void writeMemberList(OutputList &ol,bool useSections,int page, - MemberIndexList memberLists[MEMBER_INDEX_ENTRIES], + const LetterToIndexMap &memberLists, 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); typedef void (*writeLinkForMember_t)(OutputList &ol,MemberDef *md,const char *separator, @@ -2189,10 +2240,16 @@ static void writeMemberList(OutputList &ol,bool useSections,int page, bool first=TRUE; bool firstSection=TRUE; bool firstItem=TRUE; - for (pi=startIndex; pi<=endIndex; pi++) // page==-1 => pi=[0..127], page!=-1 => pi=page + MemberIndexList *ml; + SIntDict::Iterator it(memberLists); + for (it.toFirst();(ml=it.current());++it) { - MemberIndexList *ml = &memberLists[pi]; - if (ml->count()==0) continue; + if (page!=-1) + { + ml = memberLists[page]; + it.toLast(); + } + if (ml==0 || ml->count()==0) continue; ml->sort(); QListIterator mli(*ml); MemberDef *md; @@ -2211,10 +2268,8 @@ static void writeMemberList(OutputList &ol,bool useSections,int page, { if (!firstItem) ol.endItemListItem(); if (!firstSection) ol.endItemList(); - char cl[2]; - cl[0] = tolower(name.at(startIndex)); - cl[1] = 0; - QCString cs = letterToLabel(cl[0]); + QCString cs = letterToLabel(ml->letter()); + QCString cl = QString(QChar(ml->letter())).utf8(); QCString anchor=(QCString)"index_"+cs; QCString title=(QCString)"- "+cl+" -"; ol.startSection(anchor,title,SectionInfo::Subsection); @@ -2260,15 +2315,11 @@ static void writeMemberList(OutputList &ol,bool useSections,int page, void initClassMemberIndices() { - int i=0; int j=0; for (j=0;jname(); int index = getPrefixIndex(n); - uchar charCode = (uchar)n.at(index); - uint letter = charCode<128 ? tolower(charCode) : charCode; + uint letter = getUtf8CodeToLower(n,index); if (!n.isEmpty()) { bool isFriendToHide = hideFriendCompounds && @@ -2296,48 +2346,48 @@ void addClassMemberNameToIndex(MemberDef *md) QCString(md->typeString())=="friend union"); if (!(md->isFriend() && isFriendToHide)) { - g_memberIndexLetterUsed[CMHL_All][letter].append(md); + g_memberIndexLetterUsed[CMHL_All].append(letter,md); documentedClassMembers[CMHL_All]++; } if (md->isFunction() || md->isSlot() || md->isSignal()) { - g_memberIndexLetterUsed[CMHL_Functions][letter].append(md); + g_memberIndexLetterUsed[CMHL_Functions].append(letter,md); documentedClassMembers[CMHL_Functions]++; } else if (md->isVariable()) { - g_memberIndexLetterUsed[CMHL_Variables][letter].append(md); + g_memberIndexLetterUsed[CMHL_Variables].append(letter,md); documentedClassMembers[CMHL_Variables]++; } else if (md->isTypedef()) { - g_memberIndexLetterUsed[CMHL_Typedefs][letter].append(md); + g_memberIndexLetterUsed[CMHL_Typedefs].append(letter,md); documentedClassMembers[CMHL_Typedefs]++; } else if (md->isEnumerate()) { - g_memberIndexLetterUsed[CMHL_Enums][letter].append(md); + g_memberIndexLetterUsed[CMHL_Enums].append(letter,md); documentedClassMembers[CMHL_Enums]++; } else if (md->isEnumValue()) { - g_memberIndexLetterUsed[CMHL_EnumValues][letter].append(md); + g_memberIndexLetterUsed[CMHL_EnumValues].append(letter,md); documentedClassMembers[CMHL_EnumValues]++; } else if (md->isProperty()) { - g_memberIndexLetterUsed[CMHL_Properties][letter].append(md); + g_memberIndexLetterUsed[CMHL_Properties].append(letter,md); documentedClassMembers[CMHL_Properties]++; } else if (md->isEvent()) { - g_memberIndexLetterUsed[CMHL_Events][letter].append(md); + g_memberIndexLetterUsed[CMHL_Events].append(letter,md); documentedClassMembers[CMHL_Events]++; } else if (md->isRelated() || md->isForeign() || (md->isFriend() && !isFriendToHide)) { - g_memberIndexLetterUsed[CMHL_Related][letter].append(md); + g_memberIndexLetterUsed[CMHL_Related].append(letter,md); documentedClassMembers[CMHL_Related]++; } } @@ -2348,15 +2398,11 @@ void addClassMemberNameToIndex(MemberDef *md) void initNamespaceMemberIndices() { - int i=0; int j=0; for (j=0;jname(); int index = getPrefixIndex(n); - uchar charCode = (uchar)n.at(index); - uint letter = charCode<128 ? tolower(charCode) : charCode; + uint letter = getUtf8CodeToLower(n,index); if (!n.isEmpty()) { - g_namespaceIndexLetterUsed[NMHL_All][letter].append(md); + g_namespaceIndexLetterUsed[NMHL_All].append(letter,md); documentedNamespaceMembers[NMHL_All]++; if (md->isFunction()) { - g_namespaceIndexLetterUsed[NMHL_Functions][letter].append(md); + g_namespaceIndexLetterUsed[NMHL_Functions].append(letter,md); documentedNamespaceMembers[NMHL_Functions]++; } else if (md->isVariable()) { - g_namespaceIndexLetterUsed[NMHL_Variables][letter].append(md); + g_namespaceIndexLetterUsed[NMHL_Variables].append(letter,md); documentedNamespaceMembers[NMHL_Variables]++; } else if (md->isTypedef()) { - g_namespaceIndexLetterUsed[NMHL_Typedefs][letter].append(md); + g_namespaceIndexLetterUsed[NMHL_Typedefs].append(letter,md); documentedNamespaceMembers[NMHL_Typedefs]++; } else if (md->isEnumerate()) { - g_namespaceIndexLetterUsed[NMHL_Enums][letter].append(md); + g_namespaceIndexLetterUsed[NMHL_Enums].append(letter,md); documentedNamespaceMembers[NMHL_Enums]++; } else if (md->isEnumValue()) { - g_namespaceIndexLetterUsed[NMHL_EnumValues][letter].append(md); + g_namespaceIndexLetterUsed[NMHL_EnumValues].append(letter,md); documentedNamespaceMembers[NMHL_EnumValues]++; } } @@ -2407,15 +2452,11 @@ void addNamespaceMemberNameToIndex(MemberDef *md) void initFileMemberIndices() { - int i=0; int j=0; for (j=0;jname(); int index = getPrefixIndex(n); - uchar charCode = (uchar)n.at(index); - uint letter = charCode<128 ? tolower(charCode) : charCode; + uint letter = getUtf8CodeToLower(n,index); if (!n.isEmpty()) { - g_fileIndexLetterUsed[FMHL_All][letter].append(md); + g_fileIndexLetterUsed[FMHL_All].append(letter,md); documentedFileMembers[FMHL_All]++; if (md->isFunction()) { - g_fileIndexLetterUsed[FMHL_Functions][letter].append(md); + g_fileIndexLetterUsed[FMHL_Functions].append(letter,md); documentedFileMembers[FMHL_Functions]++; } else if (md->isVariable()) { - g_fileIndexLetterUsed[FMHL_Variables][letter].append(md); + g_fileIndexLetterUsed[FMHL_Variables].append(letter,md); documentedFileMembers[FMHL_Variables]++; } else if (md->isTypedef()) { - g_fileIndexLetterUsed[FMHL_Typedefs][letter].append(md); + g_fileIndexLetterUsed[FMHL_Typedefs].append(letter,md); documentedFileMembers[FMHL_Typedefs]++; } else if (md->isEnumerate()) { - g_fileIndexLetterUsed[FMHL_Enums][letter].append(md); + g_fileIndexLetterUsed[FMHL_Enums].append(letter,md); documentedFileMembers[FMHL_Enums]++; } else if (md->isEnumValue()) { - g_fileIndexLetterUsed[FMHL_EnumValues][letter].append(md); + g_fileIndexLetterUsed[FMHL_EnumValues].append(letter,md); documentedFileMembers[FMHL_EnumValues]++; } else if (md->isDefine()) { - g_fileIndexLetterUsed[FMHL_Defines][letter].append(md); + g_fileIndexLetterUsed[FMHL_Defines].append(letter,md); documentedFileMembers[FMHL_Defines]++; } } @@ -2470,31 +2510,30 @@ void addFileMemberNameToIndex(MemberDef *md) //---------------------------------------------------------------------------- static void writeQuickMemberIndex(OutputList &ol, - MemberIndexList charUsed[MEMBER_INDEX_ENTRIES],int page, + const LetterToIndexMap &charUsed,uint page, QCString fullName,bool multiPage) { bool first=TRUE; - int i; startQuickIndexList(ol,TRUE); - for (i=33;i<127;i++) - { - char is[2];is[0]=(char)i;is[1]='\0'; - QCString ci = letterToLabel((char)i); - if (charUsed[i].count()>0) - { - QCString anchor; - QCString extension=Doxygen::htmlFileExtension; - if (!multiPage) - anchor="#index_"; - else if (first) - anchor=fullName+extension+"#index_"; - else - anchor=fullName+QCString().sprintf("_0x%02x",i)+extension+"#index_"; - startQuickIndexItem(ol,anchor+ci,i==page,TRUE,first); - ol.writeString(is); - endQuickIndexItem(ol); - first=FALSE; - } + SIntDict::Iterator it(charUsed); + MemberIndexList *ml; + for (it.toFirst();(ml=it.current());++it) + { + uint i = ml->letter(); + QCString is = letterToLabel(i); + QCString ci = QString(QChar(i)).utf8(); + QCString anchor; + QCString extension=Doxygen::htmlFileExtension; + if (!multiPage) + anchor="#index_"; + else if (first) + anchor=fullName+extension+"#index_"; + else + anchor=fullName+"_"+letterToLabel(i)+extension+"#index_"; + startQuickIndexItem(ol,anchor+ci,i==page,TRUE,first); + ol.writeString(is); + endQuickIndexItem(ol); + first=FALSE; } endQuickIndexList(ol); } @@ -2534,15 +2573,13 @@ static const CmhlInfo *getCmhlInfo(int hl) static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight hl) { if (documentedClassMembers[hl]==0) return; - + static bool disableIndex = Config_getBool("DISABLE_INDEX"); bool multiPageIndex=FALSE; - int numPages=1; if (documentedClassMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX) { multiPageIndex=TRUE; - numPages=127; } ol.pushGeneratorState(); @@ -2557,99 +2594,96 @@ static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight h if (addToIndex) { Doxygen::indexList->addContentsItem(multiPageIndex,getCmhlInfo(hl)->title,0, - getCmhlInfo(hl)->fname,0,multiPageIndex,TRUE); + getCmhlInfo(hl)->fname,0,multiPageIndex,TRUE); if (multiPageIndex) Doxygen::indexList->incContentsDepth(); } - int page; bool first=TRUE; - for (page=0;page::Iterator it(g_memberIndexLetterUsed[hl]); + MemberIndexList *ml; + for (it.toFirst();(ml=it.current());++it) { - if (!multiPageIndex || g_memberIndexLetterUsed[hl][page].count()>0) - { - QCString fileName = getCmhlInfo(hl)->fname; - if (multiPageIndex) - { - if (!first) - { - fileName+=QCString().sprintf("_0x%02x",page); - } - char cs[2]; - cs[0]=page; - cs[1]=0; - if (addToIndex) - { - Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE); - } + uint page = ml->letter(); + QCString fileName = getCmhlInfo(hl)->fname; + if (multiPageIndex) + { + if (!first) + { + fileName+="_"+letterToLabel(page); } - bool quickIndex = documentedClassMembers[hl]>maxItemsBeforeQuickIndex; - - ol.startFile(fileName+extension,0,title); - ol.startQuickIndices(); - if (!disableIndex) + QCString cs = QString(QChar(page)).utf8(); + if (addToIndex) { - ol.writeQuickLinks(TRUE,HLI_Functions,0); - startQuickIndexList(ol); - - // index item for global member list - startQuickIndexItem(ol, - getCmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==CMHL_All,TRUE,first); - ol.writeString(fixSpaces(getCmhlInfo(0)->title)); - endQuickIndexItem(ol); - - int i; - // index items per category member lists - for (i=1;i0) - { - startQuickIndexItem(ol,getCmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first); - ol.writeString(fixSpaces(getCmhlInfo(i)->title)); - //printf("multiPageIndex=%d first=%d fileName=%s file=%s title=%s\n", - // multiPageIndex,first,fileName.data(),getCmhlInfo(i)->fname,getCmhlInfo(i)->title.data()); - endQuickIndexItem(ol); - } - } + Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE); + } + } + bool quickIndex = documentedClassMembers[hl]>maxItemsBeforeQuickIndex; - endQuickIndexList(ol); + ol.startFile(fileName+extension,0,title); + ol.startQuickIndices(); + if (!disableIndex) + { + ol.writeQuickLinks(TRUE,HLI_Functions,0); + startQuickIndexList(ol); - // quick alphabetical index - if (quickIndex) + // index item for global member list + startQuickIndexItem(ol, + getCmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==CMHL_All,TRUE,first); + ol.writeString(fixSpaces(getCmhlInfo(0)->title)); + endQuickIndexItem(ol); + + int i; + // index items per category member lists + for (i=1;i0) { - writeQuickMemberIndex(ol,g_memberIndexLetterUsed[hl],page, - getCmhlInfo(hl)->fname,multiPageIndex); + startQuickIndexItem(ol,getCmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first); + ol.writeString(fixSpaces(getCmhlInfo(i)->title)); + //printf("multiPageIndex=%d first=%d fileName=%s file=%s title=%s\n", + // multiPageIndex,first,fileName.data(),getCmhlInfo(i)->fname,getCmhlInfo(i)->title.data()); + endQuickIndexItem(ol); } } - ol.endQuickIndices(); - ol.writeSplitBar(fileName); - ol.writeSearchInfo(); - ol.startContents(); + endQuickIndexList(ol); - if (hl==CMHL_All) - { - ol.startTextBlock(); - ol.parseText(lne ? lne->intro() : theTranslator->trCompoundMembersDescription(Config_getBool("EXTRACT_ALL"))); - ol.endTextBlock(); - } - else + // quick alphabetical index + if (quickIndex) { - // hack to work around a mozilla bug, which refuses to switch to - // normal lists otherwise - ol.writeString(" "); + writeQuickMemberIndex(ol,g_memberIndexLetterUsed[hl],page, + getCmhlInfo(hl)->fname,multiPageIndex); } - //ol.newParagraph(); // FIXME:PARA - writeMemberList(ol,quickIndex, - multiPageIndex?page:-1, - g_memberIndexLetterUsed[hl], - Definition::TypeClass); - endFile(ol); - first=FALSE; } + ol.endQuickIndices(); + ol.writeSplitBar(fileName); + ol.writeSearchInfo(); + + ol.startContents(); + + if (hl==CMHL_All) + { + ol.startTextBlock(); + ol.parseText(lne ? lne->intro() : theTranslator->trCompoundMembersDescription(Config_getBool("EXTRACT_ALL"))); + ol.endTextBlock(); + } + else + { + // hack to work around a mozilla bug, which refuses to switch to + // normal lists otherwise + ol.writeString(" "); + } + + writeMemberList(ol,quickIndex, + multiPageIndex?page:-1, + g_memberIndexLetterUsed[hl], + Definition::TypeClass); + endFile(ol); + first=FALSE; } if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth(); - + ol.popGeneratorState(); } @@ -2716,11 +2750,9 @@ static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl) static bool disableIndex = Config_getBool("DISABLE_INDEX"); bool multiPageIndex=FALSE; - int numPages=1; if (documentedFileMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX) { multiPageIndex=TRUE; - numPages=127; } ol.pushGeneratorState(); @@ -2734,94 +2766,90 @@ static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl) if (addToIndex) { Doxygen::indexList->addContentsItem(multiPageIndex,getFmhlInfo(hl)->title,0, - getFmhlInfo(hl)->fname,0,multiPageIndex,TRUE); + getFmhlInfo(hl)->fname,0,multiPageIndex,TRUE); if (multiPageIndex) Doxygen::indexList->incContentsDepth(); } - int page; bool first=TRUE; - for (page=0;page::Iterator it(g_fileIndexLetterUsed[hl]); + MemberIndexList *ml; + for (it.toFirst();(ml=it.current());++it) { - if (!multiPageIndex || g_fileIndexLetterUsed[hl][page].count()>0) + uint page = ml->letter(); + QCString fileName = getFmhlInfo(hl)->fname; + if (multiPageIndex) { - QCString fileName = getFmhlInfo(hl)->fname; - if (multiPageIndex) + if (!first) { - if (!first) - { - fileName+=QCString().sprintf("_0x%02x",page); - } - char cs[2]; - cs[0]=page; - cs[1]=0; - if (addToIndex) - { - Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE); - } + fileName+="_"+letterToLabel(page); } - bool quickIndex = documentedFileMembers[hl]>maxItemsBeforeQuickIndex; - - ol.startFile(fileName+extension,0,title); - ol.startQuickIndices(); - if (!disableIndex) + QCString cs = QString(QChar(page)).utf8(); + if (addToIndex) { - ol.writeQuickLinks(TRUE,HLI_Globals,0); - startQuickIndexList(ol); - - // index item for all file member lists - startQuickIndexItem(ol, - getFmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==FMHL_All,TRUE,first); - ol.writeString(fixSpaces(getFmhlInfo(0)->title)); - endQuickIndexItem(ol); - - int i; - // index items for per category member lists - for (i=1;i0) - { - startQuickIndexItem(ol, - getFmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first); - ol.writeString(fixSpaces(getFmhlInfo(i)->title)); - endQuickIndexItem(ol); - } - } + Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE); + } + } + bool quickIndex = documentedFileMembers[hl]>maxItemsBeforeQuickIndex; - endQuickIndexList(ol); + ol.startFile(fileName+extension,0,title); + ol.startQuickIndices(); + if (!disableIndex) + { + ol.writeQuickLinks(TRUE,HLI_Globals,0); + startQuickIndexList(ol); + + // index item for all file member lists + startQuickIndexItem(ol, + getFmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==FMHL_All,TRUE,first); + ol.writeString(fixSpaces(getFmhlInfo(0)->title)); + endQuickIndexItem(ol); - if (quickIndex) + int i; + // index items for per category member lists + for (i=1;i0) { - writeQuickMemberIndex(ol,g_fileIndexLetterUsed[hl],page, - getFmhlInfo(hl)->fname,multiPageIndex); + startQuickIndexItem(ol, + getFmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first); + ol.writeString(fixSpaces(getFmhlInfo(i)->title)); + endQuickIndexItem(ol); } } - ol.endQuickIndices(); - ol.writeSplitBar(fileName); - ol.writeSearchInfo(); - ol.startContents(); + endQuickIndexList(ol); - if (hl==FMHL_All) - { - ol.startTextBlock(); - ol.parseText(lne ? lne->intro() : theTranslator->trFileMembersDescription(Config_getBool("EXTRACT_ALL"))); - ol.endTextBlock(); - } - else + if (quickIndex) { - // hack to work around a mozilla bug, which refuses to switch to - // normal lists otherwise - ol.writeString(" "); + writeQuickMemberIndex(ol,g_fileIndexLetterUsed[hl],page, + getFmhlInfo(hl)->fname,multiPageIndex); } - //ol.newParagraph(); // FIXME:PARA - //writeFileMemberList(ol,quickIndex,hl,page); - writeMemberList(ol,quickIndex, - multiPageIndex?page:-1, - g_fileIndexLetterUsed[hl], - Definition::TypeFile); - endFile(ol); - first=FALSE; } + ol.endQuickIndices(); + ol.writeSplitBar(fileName); + ol.writeSearchInfo(); + + ol.startContents(); + + if (hl==FMHL_All) + { + ol.startTextBlock(); + ol.parseText(lne ? lne->intro() : theTranslator->trFileMembersDescription(Config_getBool("EXTRACT_ALL"))); + ol.endTextBlock(); + } + else + { + // hack to work around a mozilla bug, which refuses to switch to + // normal lists otherwise + ol.writeString(" "); + } + + writeMemberList(ol,quickIndex, + multiPageIndex?page:-1, + g_fileIndexLetterUsed[hl], + Definition::TypeFile); + endFile(ol); + first=FALSE; } if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth(); ol.popGeneratorState(); @@ -2890,11 +2918,9 @@ static void writeNamespaceMemberIndexFiltered(OutputList &ol, bool multiPageIndex=FALSE; - int numPages=1; if (documentedNamespaceMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX) { multiPageIndex=TRUE; - numPages=127; } ol.pushGeneratorState(); @@ -2908,95 +2934,90 @@ static void writeNamespaceMemberIndexFiltered(OutputList &ol, if (addToIndex) { Doxygen::indexList->addContentsItem(multiPageIndex,getNmhlInfo(hl)->title,0, - getNmhlInfo(hl)->fname,0,multiPageIndex,TRUE); + getNmhlInfo(hl)->fname,0,multiPageIndex,TRUE); if (multiPageIndex) Doxygen::indexList->incContentsDepth(); } - int page; bool first=TRUE; - for (page=0;page::Iterator it(g_namespaceIndexLetterUsed[hl]); + MemberIndexList *ml; + for (it.toFirst();(ml=it.current());++it) { - if (!multiPageIndex || g_namespaceIndexLetterUsed[hl][page].count()>0) + uint page = ml->letter(); + QCString fileName = getNmhlInfo(hl)->fname; + if (multiPageIndex) { - QCString fileName = getNmhlInfo(hl)->fname; - if (multiPageIndex) + if (!first) { - if (!first) - { - fileName+=QCString().sprintf("_0x%02x",page); - } - char cs[2]; - cs[0]=page; - cs[1]=0; - if (addToIndex) - { - Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE); - } + fileName+="_"+letterToLabel(page); } - bool quickIndex = documentedNamespaceMembers[hl]>maxItemsBeforeQuickIndex; - - ol.startFile(fileName+extension,0,title); - ol.startQuickIndices(); - if (!disableIndex) + QCString cs = QString(QChar(page)).utf8(); + if (addToIndex) { - ol.writeQuickLinks(TRUE,HLI_NamespaceMembers,0); - startQuickIndexList(ol); - - // index item for all namespace member lists - startQuickIndexItem(ol, - getNmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==NMHL_All,TRUE,first); - ol.writeString(fixSpaces(getNmhlInfo(0)->title)); - endQuickIndexItem(ol); - - int i; - // index items per category member lists - for (i=1;i0) - { - startQuickIndexItem(ol, - getNmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first); - ol.writeString(fixSpaces(getNmhlInfo(i)->title)); - endQuickIndexItem(ol); - } - } + Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE); + } + } + bool quickIndex = documentedNamespaceMembers[hl]>maxItemsBeforeQuickIndex; - endQuickIndexList(ol); + ol.startFile(fileName+extension,0,title); + ol.startQuickIndices(); + if (!disableIndex) + { + ol.writeQuickLinks(TRUE,HLI_NamespaceMembers,0); + startQuickIndexList(ol); - if (quickIndex) + // index item for all namespace member lists + startQuickIndexItem(ol, + getNmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==NMHL_All,TRUE,first); + ol.writeString(fixSpaces(getNmhlInfo(0)->title)); + endQuickIndexItem(ol); + + int i; + // index items per category member lists + for (i=1;i0) { - writeQuickMemberIndex(ol,g_namespaceIndexLetterUsed[hl],page, - getNmhlInfo(hl)->fname,multiPageIndex); + startQuickIndexItem(ol, + getNmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first); + ol.writeString(fixSpaces(getNmhlInfo(i)->title)); + endQuickIndexItem(ol); } - } - ol.endQuickIndices(); - ol.writeSplitBar(fileName); - ol.writeSearchInfo(); - ol.startContents(); + endQuickIndexList(ol); - if (hl==NMHL_All) - { - ol.startTextBlock(); - ol.parseText(lne ? lne->intro() : theTranslator->trNamespaceMemberDescription(Config_getBool("EXTRACT_ALL"))); - ol.endTextBlock(); - } - else + if (quickIndex) { - // hack to work around a mozilla bug, which refuses to switch to - // normal lists otherwise - ol.writeString(" "); + writeQuickMemberIndex(ol,g_namespaceIndexLetterUsed[hl],page, + getNmhlInfo(hl)->fname,multiPageIndex); } - //ol.newParagraph(); // FIXME:PARA - - //writeNamespaceMemberList(ol,quickIndex,hl,page); - writeMemberList(ol,quickIndex, - multiPageIndex?page:-1, - g_namespaceIndexLetterUsed[hl], - Definition::TypeNamespace); - endFile(ol); + + } + ol.endQuickIndices(); + ol.writeSplitBar(fileName); + ol.writeSearchInfo(); + + ol.startContents(); + + if (hl==NMHL_All) + { + ol.startTextBlock(); + ol.parseText(lne ? lne->intro() : theTranslator->trNamespaceMemberDescription(Config_getBool("EXTRACT_ALL"))); + ol.endTextBlock(); } + else + { + // hack to work around a mozilla bug, which refuses to switch to + // normal lists otherwise + ol.writeString(" "); + } + + writeMemberList(ol,quickIndex, + multiPageIndex?page:-1, + g_namespaceIndexLetterUsed[hl], + Definition::TypeNamespace); + endFile(ol); } if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth(); ol.popGeneratorState(); @@ -3095,167 +3116,6 @@ static void writeExampleIndex(OutputList &ol) //---------------------------------------------------------------------------- -template -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;i0; - 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 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) { docPages=indexPages=0; diff --git a/src/search.js b/src/search.js index 3ed3f90..10cee88 100644 --- a/src/search.js +++ b/src/search.js @@ -5,7 +5,7 @@ function convertToId(search) { var c = search.charAt(i); var cn = c.charCodeAt(0); - if (c.match(/[a-z0-9]/)) + if (c.match(/[a-z0-9\u0080-\uFFFF]/)) { result+=c; } @@ -310,22 +310,20 @@ function SearchBox(name, resultsPath, inFrame, label) var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); var code = searchValue.toLowerCase().charCodeAt(0); - var hexCode; - if (code<16) + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair { - hexCode="0"+code.toString(16); - } - else - { - hexCode=code.toString(16); + idxChar = searchValue.substr(0, 2); } var resultsPage; var resultsPageWithSearch; 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'; resultsPageWithSearch = resultsPage+'?'+escape(searchValue); hasResultsPage = true; diff --git a/src/search_functions.php b/src/search_functions.php index acd7f3c..5ad2e5d 100644 --- a/src/search_functions.php +++ b/src/search_functions.php @@ -358,7 +358,7 @@ function main() $sorted = run_query($query); // Now output the HTML stuff... // 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($sorted); end_page(); diff --git a/src/search_functions_php.h b/src/search_functions_php.h index b09c259..9c7c3e3 100644 --- a/src/search_functions_php.h +++ b/src/search_functions_php.h @@ -358,7 +358,7 @@ " $sorted = run_query($query);\n" " // Now output the HTML stuff...\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($sorted);\n" " end_page();\n" diff --git a/src/search_js.h b/src/search_js.h index 985d03c..422f580 100644 --- a/src/search_js.h +++ b/src/search_js.h @@ -5,7 +5,7 @@ " {\n" " var c = search.charAt(i);\n" " var cn = c.charCodeAt(0);\n" -" if (c.match(/[a-z0-9]/))\n" +" if (c.match(/[a-z0-9\\u0080-\\uFFFF]/))\n" " {\n" " result+=c;\n" " }\n" @@ -310,22 +310,20 @@ " var searchValue = this.DOMSearchField().value.replace(/^ +/, \"\");\n" "\n" " var code = searchValue.toLowerCase().charCodeAt(0);\n" -" var hexCode;\n" -" if (code<16) \n" +" var idxChar = searchValue.substr(0, 1).toLowerCase();\n" +" if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair\n" " {\n" -" hexCode=\"0\"+code.toString(16);\n" -" }\n" -" else \n" -" {\n" -" hexCode=code.toString(16);\n" +" idxChar = searchValue.substr(0, 2);\n" " }\n" "\n" " var resultsPage;\n" " var resultsPageWithSearch;\n" " var hasResultsPage;\n" "\n" -" if (indexSectionsWithContent[this.searchIndex].charAt(code) == '1')\n" +" var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar);\n" +" if (idx!=-1)\n" " {\n" +" var hexCode=idx.toString(16);\n" " resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html';\n" " resultsPageWithSearch = resultsPage+'?'+escape(searchValue);\n" " hasResultsPage = true;\n" diff --git a/src/searchindex.cpp b/src/searchindex.cpp index 0380b33..d2f49ad 100644 --- a/src/searchindex.cpp +++ b/src/searchindex.cpp @@ -587,8 +587,6 @@ static const char search_script[]= #include "search_js.h" ; -#define MEMBER_INDEX_ENTRIES 256 - #define SEARCH_INDEX_ALL 0 #define SEARCH_INDEX_CLASSES 1 #define SEARCH_INDEX_NAMESPACES 2 @@ -606,21 +604,31 @@ static const char search_script[]= #define SEARCH_INDEX_PAGES 14 #define NUM_SEARCH_INDICES 15 -class SearchIndexList : public SDict< QList > +class SearchDefinitionList : public QList +{ + public: + SearchDefinitionList(uint letter) : m_letter(letter) {} + uint letter() const { return m_letter; } + private: + uint m_letter; +}; + +class SearchIndexList : public SDict< SearchDefinitionList > { public: - SearchIndexList(int size=17) : SDict< QList >(size,FALSE) + typedef Definition ElementType; + SearchIndexList(uint letter) : SDict(17,FALSE), m_letter(letter) { setAutoDelete(TRUE); } ~SearchIndexList() {} void append(Definition *d) { - QList *l = find(d->name()); + SearchDefinitionList *l = find(d->name()); if (l==0) { - l=new QList; - SDict< QList >::append(d->name(),l); + l=new SearchDefinitionList(m_letter); + SDict::append(d->name(),l); } l->append(d); } @@ -632,10 +640,13 @@ class SearchIndexList : public SDict< QList > QCString n2 = md2->first()->localName(); return qstricmp(n1.data(),n2.data()); } + uint letter() const { return m_letter; } + private: + uint m_letter; }; static void addMemberToSearchIndex( - SearchIndexList symbols[NUM_SEARCH_INDICES][MEMBER_INDEX_ENTRIES], + LetterToIndexMap symbols[NUM_SEARCH_INDICES], int symbolCount[NUM_SEARCH_INDICES], MemberDef *md) { @@ -653,58 +664,57 @@ static void addMemberToSearchIndex( ) { QCString n = md->name(); - uchar charCode = (uchar)n.at(0); - uint letter = charCode<128 ? tolower(charCode) : charCode; if (!n.isEmpty()) { + uint letter = getUtf8CodeToLower(n,0); bool isFriendToHide = hideFriendCompounds && (QCString(md->typeString())=="friend class" || QCString(md->typeString())=="friend struct" || QCString(md->typeString())=="friend union"); if (!(md->isFriend() && isFriendToHide)) { - symbols[SEARCH_INDEX_ALL][letter].append(md); + symbols[SEARCH_INDEX_ALL].append(letter,md); symbolCount[SEARCH_INDEX_ALL]++; } 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]++; } else if (md->isVariable()) { - symbols[SEARCH_INDEX_VARIABLES][letter].append(md); + symbols[SEARCH_INDEX_VARIABLES].append(letter,md); symbolCount[SEARCH_INDEX_VARIABLES]++; } else if (md->isTypedef()) { - symbols[SEARCH_INDEX_TYPEDEFS][letter].append(md); + symbols[SEARCH_INDEX_TYPEDEFS].append(letter,md); symbolCount[SEARCH_INDEX_TYPEDEFS]++; } else if (md->isEnumerate()) { - symbols[SEARCH_INDEX_ENUMS][letter].append(md); + symbols[SEARCH_INDEX_ENUMS].append(letter,md); symbolCount[SEARCH_INDEX_ENUMS]++; } else if (md->isEnumValue()) { - symbols[SEARCH_INDEX_ENUMVALUES][letter].append(md); + symbols[SEARCH_INDEX_ENUMVALUES].append(letter,md); symbolCount[SEARCH_INDEX_ENUMVALUES]++; } else if (md->isProperty()) { - symbols[SEARCH_INDEX_PROPERTIES][letter].append(md); + symbols[SEARCH_INDEX_PROPERTIES].append(letter,md); symbolCount[SEARCH_INDEX_PROPERTIES]++; } else if (md->isEvent()) { - symbols[SEARCH_INDEX_EVENTS][letter].append(md); + symbols[SEARCH_INDEX_EVENTS].append(letter,md); symbolCount[SEARCH_INDEX_EVENTS]++; } else if (md->isRelated() || md->isForeign() || (md->isFriend() && !isFriendToHide)) { - symbols[SEARCH_INDEX_RELATED][letter].append(md); + symbols[SEARCH_INDEX_RELATED].append(letter,md); symbolCount[SEARCH_INDEX_RELATED]++; } } @@ -716,47 +726,48 @@ static void addMemberToSearchIndex( ) { QCString n = md->name(); - uchar charCode = (uchar)n.at(0); - uint letter = charCode<128 ? tolower(charCode) : charCode; 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]++; if (md->isFunction()) { - symbols[SEARCH_INDEX_FUNCTIONS][letter].append(md); + symbols[SEARCH_INDEX_FUNCTIONS].append(letter,md); symbolCount[SEARCH_INDEX_FUNCTIONS]++; } else if (md->isVariable()) { - symbols[SEARCH_INDEX_VARIABLES][letter].append(md); + symbols[SEARCH_INDEX_VARIABLES].append(letter,md); symbolCount[SEARCH_INDEX_VARIABLES]++; } else if (md->isTypedef()) { - symbols[SEARCH_INDEX_TYPEDEFS][letter].append(md); + symbols[SEARCH_INDEX_TYPEDEFS].append(letter,md); symbolCount[SEARCH_INDEX_TYPEDEFS]++; } else if (md->isEnumerate()) { - symbols[SEARCH_INDEX_ENUMS][letter].append(md); + symbols[SEARCH_INDEX_ENUMS].append(letter,md); symbolCount[SEARCH_INDEX_ENUMS]++; } else if (md->isEnumValue()) { - symbols[SEARCH_INDEX_ENUMVALUES][letter].append(md); + symbols[SEARCH_INDEX_ENUMVALUES].append(letter,md); symbolCount[SEARCH_INDEX_ENUMVALUES]++; } else if (md->isDefine()) { - symbols[SEARCH_INDEX_DEFINES][letter].append(md); + symbols[SEARCH_INDEX_DEFINES].append(letter,md); symbolCount[SEARCH_INDEX_DEFINES]++; } } } } +// see also function convertToId() in search.js, which should match in +// behaviour static QCString searchId(const QCString &s) { int c; @@ -765,11 +776,15 @@ static QCString searchId(const QCString &s) for (i=0;i='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); } - else + else // other 'unprintable' characters { char val[4]; sprintf(val,"_%02x",(uchar)c); @@ -780,7 +795,7 @@ static QCString searchId(const QCString &s) } static int g_searchIndexCount[NUM_SEARCH_INDICES]; -static SearchIndexList g_searchIndexSymbols[NUM_SEARCH_INDICES][MEMBER_INDEX_ENTRIES]; +static LetterToIndexMap g_searchIndexSymbols[NUM_SEARCH_INDICES]; static const char *g_searchIndexName[NUM_SEARCH_INDICES] = { "all", @@ -834,12 +849,11 @@ void writeJavascriptSearchIndex() ClassDef *cd; for (;(cd=cli.current());++cli) { - uchar charCode = (uchar)cd->localName().at(0); - uint letter = charCode<128 ? tolower(charCode) : charCode; + uint letter = getUtf8CodeToLower(cd->localName(),0); if (cd->isLinkable() && isId(letter)) { - g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(cd); - g_searchIndexSymbols[SEARCH_INDEX_CLASSES][letter].append(cd); + g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,cd); + g_searchIndexSymbols[SEARCH_INDEX_CLASSES].append(letter,cd); g_searchIndexCount[SEARCH_INDEX_ALL]++; g_searchIndexCount[SEARCH_INDEX_CLASSES]++; } @@ -850,12 +864,11 @@ void writeJavascriptSearchIndex() NamespaceDef *nd; for (;(nd=nli.current());++nli) { - uchar charCode = (uchar)nd->name().at(0); - uint letter = charCode<128 ? tolower(charCode) : charCode; + uint letter = getUtf8CodeToLower(nd->name(),0); if (nd->isLinkable() && isId(letter)) { - g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(nd); - g_searchIndexSymbols[SEARCH_INDEX_NAMESPACES][letter].append(nd); + g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,nd); + g_searchIndexSymbols[SEARCH_INDEX_NAMESPACES].append(letter,nd); g_searchIndexCount[SEARCH_INDEX_ALL]++; g_searchIndexCount[SEARCH_INDEX_NAMESPACES]++; } @@ -870,12 +883,11 @@ void writeJavascriptSearchIndex() FileDef *fd; for (;(fd=fni.current());++fni) { - uchar charCode = (uchar)fd->name().at(0); - uint letter = charCode<128 ? tolower(charCode) : charCode; + uint letter = getUtf8CodeToLower(fd->name(),0); if (fd->isLinkable() && isId(letter)) { - g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(fd); - g_searchIndexSymbols[SEARCH_INDEX_FILES][letter].append(fd); + g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,fd); + g_searchIndexSymbols[SEARCH_INDEX_FILES].append(letter,fd); g_searchIndexCount[SEARCH_INDEX_ALL]++; g_searchIndexCount[SEARCH_INDEX_FILES]++; } @@ -930,8 +942,8 @@ void writeJavascriptSearchIndex() uint letter = charCode<128 ? tolower(charCode) : charCode; if (isId(letter)) { - g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(gd); - g_searchIndexSymbols[SEARCH_INDEX_GROUPS][letter].append(gd); + g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,gd); + g_searchIndexSymbols[SEARCH_INDEX_GROUPS].append(letter,gd); g_searchIndexCount[SEARCH_INDEX_ALL]++; g_searchIndexCount[SEARCH_INDEX_GROUPS]++; } @@ -953,8 +965,8 @@ void writeJavascriptSearchIndex() uint letter = charCode<128 ? tolower(charCode) : charCode; if (isId(letter)) { - g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(pd); - g_searchIndexSymbols[SEARCH_INDEX_PAGES][letter].append(pd); + g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,pd); + g_searchIndexSymbols[SEARCH_INDEX_PAGES].append(letter,pd); g_searchIndexCount[SEARCH_INDEX_ALL]++; g_searchIndexCount[SEARCH_INDEX_PAGES]++; } @@ -970,8 +982,8 @@ void writeJavascriptSearchIndex() uint letter = charCode<128 ? tolower(charCode) : charCode; if (isId(letter)) { - g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(Doxygen::mainPage); - g_searchIndexSymbols[SEARCH_INDEX_PAGES][letter].append(Doxygen::mainPage); + g_searchIndexSymbols[SEARCH_INDEX_ALL].append(letter,Doxygen::mainPage); + g_searchIndexSymbols[SEARCH_INDEX_PAGES].append(letter,Doxygen::mainPage); g_searchIndexCount[SEARCH_INDEX_ALL]++; g_searchIndexCount[SEARCH_INDEX_PAGES]++; } @@ -979,122 +991,181 @@ void writeJavascriptSearchIndex() } // sort all lists - int i,p; + int i; for (i=0;i::Iterator it(g_searchIndexSymbols[i]); + SearchIndexList *sl; + for (it.toFirst();(sl=it.current());++it) { - if (g_searchIndexSymbols[i][p].count()>0) - { - g_searchIndexSymbols[i][p].sort(); - } + sl->sort(); } } // write index files QCString searchDirName = Config_getString("HTML_OUTPUT")+"/search"; - for (i=0;i::Iterator it(g_searchIndexSymbols[i]); + SearchIndexList *sl; + int p=0; + for (it.toFirst();(sl=it.current());++it,++p) // for each letter { - if (g_searchIndexSymbols[i][p].count()>0) - { - QCString baseName; - baseName.sprintf("%s_%02x",g_searchIndexName[i],p); + QCString baseName; + baseName.sprintf("%s_%x",g_searchIndexName[i],p); - QCString fileName = searchDirName + "/"+baseName+".html"; - QCString dataFileName = searchDirName + "/"+baseName+".js"; + QCString fileName = searchDirName + "/"+baseName+".html"; + QCString dataFileName = searchDirName + "/"+baseName+".js"; - QFile outFile(fileName); - QFile dataOutFile(dataFileName); - if (outFile.open(IO_WriteOnly) && dataOutFile.open(IO_WriteOnly)) + QFile outFile(fileName); + QFile dataOutFile(dataFileName); + if (outFile.open(IO_WriteOnly) && dataOutFile.open(IO_WriteOnly)) + { + { + FTextStream t(&outFile); + + t << "" << endl; + t << "" << endl; + t << "" << endl; + t << "" << endl; + t << "" << endl; + t << "" << endl; + t << "" << endl; + t << "" << endl; + t << "" << endl; + t << "
" << endl; + t << "
" << theTranslator->trLoading() << "
" << endl; + t << "
" << endl; // here the results will be inserted + t << "" << endl; + t << "
" + << theTranslator->trSearching() << "
" << endl; + t << "
" + << theTranslator->trNoMatches() << "
" << endl; + + t << "" << endl; + t << "
" << endl; // SRIndex + t << "" << endl; + t << "" << endl; + } + FTextStream ti(&dataOutFile); + + ti << "var searchData=" << endl; + // format + // searchData[] = array of items + // searchData[x][0] = id + // searchData[x][1] = [ name + child1 + child2 + .. ] + // searchData[x][1][0] = name as shown + // searchData[x][1][y+1] = info for child y + // searchData[x][1][y+1][0] = url + // searchData[x][1][y+1][1] = 1 => target="_parent" + // searchData[x][1][y+1][2] = scope + + ti << "[" << endl; + bool firstEntry=TRUE; + + SDict::Iterator li(*sl); + SearchDefinitionList *dl; + int itemCount=0; + for (li.toFirst();(dl=li.current());++li) { + Definition *d = dl->first(); + QCString id = d->localName(); + + if (!firstEntry) + { + ti << "," << endl; + } + firstEntry=FALSE; + + QCString dispName = d->localName(); + if (d->definitionType()==Definition::TypeGroup) { - FTextStream t(&outFile); - - t << "" << endl; - t << "" << endl; - t << "" << endl; - t << "" << endl; - t << "" << endl; - t << "" << endl; - t << "" << endl; - t << "" << endl; - t << "" << endl; - t << "
" << endl; - t << "
" << theTranslator->trLoading() << "
" << endl; - t << "
" << endl; // here the results will be inserted - t << "" << endl; - t << "
" - << theTranslator->trSearching() << "
" << endl; - t << "
" - << theTranslator->trNoMatches() << "
" << endl; - - t << "" << endl; - t << "
" << endl; // SRIndex - t << "" << endl; - t << "" << endl; + dispName = ((GroupDef*)d)->groupTitle(); } - FTextStream ti(&dataOutFile); - - ti << "var searchData=" << endl; - // format - // searchData[] = array of items - // searchData[x][0] = id - // searchData[x][1] = [ name + child1 + child2 + .. ] - // searchData[x][1][0] = name as shown - // searchData[x][1][y+1] = info for child y - // searchData[x][1][y+1][0] = url - // searchData[x][1][y+1][1] = 1 => target="_parent" - // searchData[x][1][y+1][2] = scope - - ti << "[" << endl; - bool firstEntry=TRUE; - - SDict >::Iterator li(g_searchIndexSymbols[i][p]); - QList *dl; - int itemCount=0; - for (li.toFirst();(dl=li.current());++li) + else if (d->definitionType()==Definition::TypePage) { - Definition *d = dl->first(); - QCString id = d->localName(); + dispName = ((PageDef*)d)->title(); + } + ti << " ['" << searchId(dispName) << "',['" + << convertToXML(dispName) << "',["; - if (!firstEntry) + if (dl->count()==1) // item with a unique name + { + MemberDef *md = 0; + bool isMemberDef = d->definitionType()==Definition::TypeMember; + if (isMemberDef) md = (MemberDef*)d; + QCString anchor = d->anchor(); + + ti << "'" << externalRef("../",d->getReference(),TRUE) + << d->getOutputFileBase() << Doxygen::htmlFileExtension; + if (!anchor.isEmpty()) { - ti << "," << endl; + ti << "#" << anchor; } - firstEntry=FALSE; + ti << "',"; - QCString dispName = d->localName(); - if (d->definitionType()==Definition::TypeGroup) + static bool extLinksInWindow = Config_getBool("EXT_LINKS_IN_WINDOW"); + if (!extLinksInWindow || d->getReference().isEmpty()) { - dispName = ((GroupDef*)d)->groupTitle(); + ti << "1,"; } - else if (d->definitionType()==Definition::TypePage) + else { - dispName = ((PageDef*)d)->title(); + ti << "0,"; } - ti << " ['" << searchId(dispName) << "',['" - << convertToXML(dispName) << "',["; - if (dl->count()==1) // item with a unique name + if (d->getOuterScope()!=Doxygen::globalScope) + { + ti << "'" << convertToXML(d->getOuterScope()->name()) << "'"; + } + else if (md) + { + FileDef *fd = md->getBodyDef(); + if (fd==0) fd = md->getFileDef(); + if (fd) + { + ti << "'" << convertToXML(fd->localName()) << "'"; + } + } + else + { + ti << "''"; + } + ti << "]]"; + } + else // multiple items with the same name + { + QListIterator di(*dl); + bool overloadedFunction = FALSE; + Definition *prevScope = 0; + int childCount=0; + for (di.toFirst();(d=di.current());) { - MemberDef *md = 0; + ++di; + Definition *scope = d->getOuterScope(); + Definition *next = di.current(); + Definition *nextScope = 0; + MemberDef *md = 0; bool isMemberDef = d->definitionType()==Definition::TypeMember; if (isMemberDef) md = (MemberDef*)d; + if (next) nextScope = next->getOuterScope(); QCString anchor = d->anchor(); + if (childCount>0) + { + ti << "],["; + } ti << "'" << externalRef("../",d->getReference(),TRUE) - << d->getOutputFileBase() << Doxygen::htmlFileExtension; + << d->getOutputFileBase() << Doxygen::htmlFileExtension; if (!anchor.isEmpty()) { ti << "#" << anchor; @@ -1110,147 +1181,87 @@ void writeJavascriptSearchIndex() { ti << "0,"; } - - if (d->getOuterScope()!=Doxygen::globalScope) + bool found=FALSE; + overloadedFunction = ((prevScope!=0 && scope==prevScope) || + (scope && scope==nextScope) + ) && md && + (md->isFunction() || md->isSlot()); + QCString prefix; + if (md) prefix=convertToXML(md->localName()); + if (overloadedFunction) // overloaded member function { - ti << "'" << convertToXML(d->getOuterScope()->name()) << "'"; + prefix+=convertToXML(md->argsString()); + // show argument list to disambiguate overloaded functions } - else if (md) + else if (md) // unique member function { - FileDef *fd = md->getBodyDef(); - if (fd==0) fd = md->getFileDef(); - if (fd) - { - ti << "'" << convertToXML(fd->localName()) << "'"; - } + prefix+="()"; // only to show it is a function } - else + QCString name; + if (d->definitionType()==Definition::TypeClass) { - ti << "''"; + name = convertToXML(((ClassDef*)d)->displayName()); + found = TRUE; } - ti << "]]"; - } - else // multiple items with the same name - { - QListIterator di(*dl); - bool overloadedFunction = FALSE; - Definition *prevScope = 0; - int childCount=0; - for (di.toFirst();(d=di.current());) + else if (d->definitionType()==Definition::TypeNamespace) { - ++di; - Definition *scope = d->getOuterScope(); - Definition *next = di.current(); - Definition *nextScope = 0; - MemberDef *md = 0; - bool isMemberDef = d->definitionType()==Definition::TypeMember; - if (isMemberDef) md = (MemberDef*)d; - if (next) nextScope = next->getOuterScope(); - QCString anchor = d->anchor(); - - if (childCount>0) - { - ti << "],["; - } - ti << "'" << externalRef("../",d->getReference(),TRUE) - << d->getOutputFileBase() << Doxygen::htmlFileExtension; - if (!anchor.isEmpty()) - { - ti << "#" << anchor; - } - ti << "',"; - - static bool extLinksInWindow = Config_getBool("EXT_LINKS_IN_WINDOW"); - if (!extLinksInWindow || d->getReference().isEmpty()) - { - ti << "1,"; - } - else - { - ti << "0,"; - } - bool found=FALSE; - overloadedFunction = ((prevScope!=0 && scope==prevScope) || - (scope && scope==nextScope) - ) && md && - (md->isFunction() || md->isSlot()); - QCString prefix; - if (md) prefix=convertToXML(md->localName()); - if (overloadedFunction) // overloaded member function - { - prefix+=convertToXML(md->argsString()); - // show argument list to disambiguate overloaded functions - } - else if (md) // unique member function - { - prefix+="()"; // only to show it is a function - } - QCString name; - if (d->definitionType()==Definition::TypeClass) - { - name = convertToXML(((ClassDef*)d)->displayName()); - found = TRUE; - } - else if (d->definitionType()==Definition::TypeNamespace) - { - name = convertToXML(((NamespaceDef*)d)->displayName()); - found = TRUE; - } - else if (scope==0 || scope==Doxygen::globalScope) // in global scope + name = convertToXML(((NamespaceDef*)d)->displayName()); + found = TRUE; + } + else if (scope==0 || scope==Doxygen::globalScope) // in global scope + { + if (md) { - if (md) + FileDef *fd = md->getBodyDef(); + if (fd==0) fd = md->getFileDef(); + if (fd) { - FileDef *fd = md->getBodyDef(); - if (fd==0) fd = md->getFileDef(); - if (fd) - { - if (!prefix.isEmpty()) prefix+=": "; - name = prefix + convertToXML(fd->localName()); - found = TRUE; - } + if (!prefix.isEmpty()) prefix+=": "; + name = prefix + convertToXML(fd->localName()); + found = TRUE; } } - else if (md && (md->getClassDef() || md->getNamespaceDef())) - // member in class or namespace scope - { - SrcLangExt lang = md->getLanguage(); - name = convertToXML(d->getOuterScope()->qualifiedName()) - + getLanguageSpecificSeparator(lang) + prefix; - found = TRUE; - } - else if (scope) // some thing else? -> show scope - { - name = prefix + convertToXML(scope->name()); - found = TRUE; - } - if (!found) // fallback - { - name = prefix + "("+theTranslator->trGlobalNamespace()+")"; - } - - ti << "'" << name << "'"; - - prevScope = scope; - childCount++; + } + else if (md && (md->getClassDef() || md->getNamespaceDef())) + // member in class or namespace scope + { + SrcLangExt lang = md->getLanguage(); + name = convertToXML(d->getOuterScope()->qualifiedName()) + + getLanguageSpecificSeparator(lang) + prefix; + found = TRUE; + } + else if (scope) // some thing else? -> show scope + { + name = prefix + convertToXML(scope->name()); + found = TRUE; + } + if (!found) // fallback + { + name = prefix + "("+theTranslator->trGlobalNamespace()+")"; } - ti << "]]"; - } - ti << "]"; - itemCount++; - } - if (!firstEntry) - { - ti << endl; - } + ti << "'" << name << "'"; - ti << "];" << endl; + prevScope = scope; + childCount++; + } + ti << "]]"; + } + ti << "]"; + itemCount++; } - else + if (!firstEntry) { - err("Failed to open file '%s' for writing...\n",fileName.data()); + ti << endl; } + + ti << "];" << endl; + + } + else + { + err("Failed to open file '%s' for writing...\n",fileName.data()); } } } @@ -1275,9 +1286,12 @@ void writeJavascriptSearchIndex() { if (!first) t << "," << endl; t << " " << j << ": \""; - for (p=0;p::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 << "\""; first=FALSE; diff --git a/src/sortdict.h b/src/sortdict.h index 14a221b..e111075 100644 --- a/src/sortdict.h +++ b/src/sortdict.h @@ -108,7 +108,7 @@ class SDict * \param caseSensitive indicated whether the keys should be sorted * 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(this); #if AUTORESIZE @@ -454,7 +454,7 @@ class SIntDict * \param size The size of the dictionary. Should be a prime number for * best distribution of elements. */ - SIntDict(int size) : m_sizeIndex(0) + SIntDict(int size=17) : m_sizeIndex(0) { m_list = new SIntList(this); #if AUTORESIZE @@ -636,7 +636,7 @@ class SIntDict { return m_li->current(); } - + /*! Moves the iterator to the next element. * \return the new "current" element, or zero if the iterator was * already pointing at the last element. @@ -659,6 +659,76 @@ class SIntDict QListIterator *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 &dict) + { + m_di = new QIntDictIterator(*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 *m_di; + }; + }; #endif diff --git a/src/util.cpp b/src/util.cpp index 5abe4ed..60a0fe1 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -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; +} + +//-------------------------------------------------------------------------------------- + diff --git a/src/util.h b/src/util.h index 1aba005..0cbe450 100644 --- a/src/util.h +++ b/src/util.h @@ -25,6 +25,7 @@ #include #include #include "types.h" +#include "sortdict.h" //-------------------------------------------------------------------- @@ -87,6 +88,33 @@ class TextGeneratorOLImpl : public TextGeneratorIntf //-------------------------------------------------------------------- +/** @brief maps a unicode character code to a list of T::ElementType's + */ +template +class LetterToIndexMap : public SIntDict +{ + public: + LetterToIndexMap() { SIntDict::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::find((int)letter); + if (l==0) + { + l = new T(letter); + SIntDict::inSort((int)letter,l); + } + l->append(elem); + } +}; + +//-------------------------------------------------------------------- + QCString langToString(SrcLangExt lang); QCString getLanguageSpecificSeparator(SrcLangExt lang,bool classScope=FALSE); @@ -411,5 +439,9 @@ bool fileVisibleInIndex(FileDef *fd,bool &genSourceFile); 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 -- cgit v0.12
  "); - ol.writeString(s); + ol.writeString(QString(QChar(cell->letter())).utf8()); ol.writeString( "  
" "