Blame src/searchindex.cpp

Packit Service 50c9f2
/******************************************************************************
Packit Service 50c9f2
 *
Packit Service 50c9f2
 *
Packit Service 50c9f2
 *
Packit Service 50c9f2
 * Copyright (C) 1997-2015 by Dimitri van Heesch.
Packit Service 50c9f2
 *
Packit Service 50c9f2
 * Permission to use, copy, modify, and distribute this software and its
Packit Service 50c9f2
 * documentation under the terms of the GNU General Public License is hereby
Packit Service 50c9f2
 * granted. No representations are made about the suitability of this software
Packit Service 50c9f2
 * for any purpose. It is provided "as is" without express or implied warranty.
Packit Service 50c9f2
 * See the GNU General Public License for more details.
Packit Service 50c9f2
 *
Packit Service 50c9f2
 * Documents produced by Doxygen are derivative works derived from the
Packit Service 50c9f2
 * input used in their production; they are not affected by this license.
Packit Service 50c9f2
 *
Packit Service 50c9f2
 */
Packit Service 50c9f2
Packit Service 50c9f2
#include <ctype.h>
Packit Service 50c9f2
#include <assert.h>
Packit Service 50c9f2
Packit Service 50c9f2
#include <qfile.h>
Packit Service 50c9f2
#include <qregexp.h>
Packit Service 50c9f2
Packit Service 50c9f2
#include "searchindex.h"
Packit Service 50c9f2
#include "config.h"
Packit Service 50c9f2
#include "util.h"
Packit Service 50c9f2
#include "doxygen.h"
Packit Service 50c9f2
#include "language.h"
Packit Service 50c9f2
#include "pagedef.h"
Packit Service 50c9f2
#include "growbuf.h"
Packit Service 50c9f2
#include "message.h"
Packit Service 50c9f2
#include "version.h"
Packit Service 50c9f2
#include "groupdef.h"
Packit Service 50c9f2
#include "classlist.h"
Packit Service 50c9f2
#include "filedef.h"
Packit Service 50c9f2
#include "memberdef.h"
Packit Service 50c9f2
#include "filename.h"
Packit Service 50c9f2
#include "membername.h"
Packit Service 50c9f2
#include "resourcemgr.h"
Packit Service 50c9f2
Packit Service 50c9f2
// file format: (all multi-byte values are stored in big endian format)
Packit Service 50c9f2
//   4 byte header
Packit Service 50c9f2
//   256*256*4 byte index (4 bytes)
Packit Service 50c9f2
//   for each index entry: a zero terminated list of words
Packit Service 50c9f2
//   for each word: a \0 terminated string + 4 byte offset to the stats info
Packit Service 50c9f2
//   padding bytes to align at 4 byte boundary
Packit Service 50c9f2
//   for each word: the number of urls (4 bytes)
Packit Service 50c9f2
//               + for each url containing the word 8 bytes statistics
Packit Service 50c9f2
//                 (4 bytes index to url string + 4 bytes frequency counter)
Packit Service 50c9f2
//   for each url: a \0 terminated string
Packit Service 50c9f2
Packit Service 50c9f2
const int numIndexEntries = 256*256;
Packit Service 50c9f2
Packit Service 50c9f2
//--------------------------------------------------------------------
Packit Service 50c9f2
Packit Service 50c9f2
IndexWord::IndexWord(const char *word) : m_word(word), m_urls(17)
Packit Service 50c9f2
{
Packit Service 50c9f2
  m_urls.setAutoDelete(TRUE);
Packit Service 50c9f2
  //printf("IndexWord::IndexWord(%s)\n",word);
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
void IndexWord::addUrlIndex(int idx,bool hiPriority)
Packit Service 50c9f2
{
Packit Service 50c9f2
  //printf("IndexWord::addUrlIndex(%d,%d)\n",idx,hiPriority);
Packit Service 50c9f2
  URLInfo *ui = m_urls.find(idx);
Packit Service 50c9f2
  if (ui==0)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    //printf("URLInfo::URLInfo(%d)\n",idx);
Packit Service 50c9f2
    ui=new URLInfo(idx,0);
Packit Service 50c9f2
    m_urls.insert(idx,ui);
Packit Service 50c9f2
  }
Packit Service 50c9f2
  ui->freq+=2;
Packit Service 50c9f2
  if (hiPriority) ui->freq|=1; // mark as high priority document
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
//--------------------------------------------------------------------
Packit Service 50c9f2
Packit Service 50c9f2
SearchIndex::SearchIndex() : SearchIndexIntf(Internal),
Packit Service 50c9f2
      m_words(328829), m_index(numIndexEntries), m_url2IdMap(10007), m_urls(10007), m_urlIndex(-1)
Packit Service 50c9f2
{
Packit Service 50c9f2
  int i;
Packit Service 50c9f2
  m_words.setAutoDelete(TRUE);
Packit Service 50c9f2
  m_url2IdMap.setAutoDelete(TRUE);
Packit Service 50c9f2
  m_urls.setAutoDelete(TRUE);
Packit Service 50c9f2
  m_index.setAutoDelete(TRUE);
Packit Service 50c9f2
  for (i=0;i<numIndexEntries;i++) m_index.insert(i,new QList<IndexWord>);
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
void SearchIndex::setCurrentDoc(Definition *ctx,const char *anchor,bool isSourceFile)
Packit Service 50c9f2
{
Packit Service 50c9f2
  if (ctx==0) return;
Packit Service 50c9f2
  assert(!isSourceFile || ctx->definitionType()==Definition::TypeFile);
Packit Service 50c9f2
  //printf("SearchIndex::setCurrentDoc(%s,%s,%s)\n",name,baseName,anchor);
Packit Service 50c9f2
  QCString url=isSourceFile ? ((FileDef*)ctx)->getSourceFileBase() : ctx->getOutputFileBase();
Packit Service 50c9f2
  url+=Config_getString(HTML_FILE_EXTENSION);
Packit Service 50c9f2
  QCString baseUrl = url;
Packit Service 50c9f2
  if (anchor) url+=QCString("#")+anchor;
Packit Service 50c9f2
  if (!isSourceFile) baseUrl=url;
Packit Service 50c9f2
  QCString name=ctx->qualifiedName();
Packit Service 50c9f2
  if (ctx->definitionType()==Definition::TypeMember)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    MemberDef *md = (MemberDef *)ctx;
Packit Service 50c9f2
    name.prepend((md->getLanguage()==SrcLangExt_Fortran  ?
Packit Service 50c9f2
                 theTranslator->trSubprogram(TRUE,TRUE) :
Packit Service 50c9f2
                 theTranslator->trMember(TRUE,TRUE))+" ");
Packit Service 50c9f2
  }
Packit Service 50c9f2
  else // compound type
Packit Service 50c9f2
  {
Packit Service 50c9f2
    SrcLangExt lang = ctx->getLanguage();
Packit Service 50c9f2
    QCString sep = getLanguageSpecificSeparator(lang);
Packit Service 50c9f2
    if (sep!="::")
Packit Service 50c9f2
    {
Packit Service 50c9f2
      name = substitute(name,"::",sep);
Packit Service 50c9f2
    }
Packit Service 50c9f2
    switch (ctx->definitionType())
Packit Service 50c9f2
    {
Packit Service 50c9f2
      case Definition::TypePage:
Packit Service 50c9f2
        {
Packit Service 50c9f2
          PageDef *pd = (PageDef *)ctx;
Packit Service 50c9f2
          if (!pd->title().isEmpty())
Packit Service 50c9f2
          {
Packit Service 50c9f2
            name = theTranslator->trPage(TRUE,TRUE)+" "+pd->title();
Packit Service 50c9f2
          }
Packit Service 50c9f2
          else
Packit Service 50c9f2
          {
Packit Service 50c9f2
            name = theTranslator->trPage(TRUE,TRUE)+" "+pd->name();
Packit Service 50c9f2
          }
Packit Service 50c9f2
        }
Packit Service 50c9f2
        break;
Packit Service 50c9f2
      case Definition::TypeClass:
Packit Service 50c9f2
        {
Packit Service 50c9f2
          ClassDef *cd = (ClassDef *)ctx;
Packit Service 50c9f2
          name.prepend(cd->compoundTypeString()+" ");
Packit Service 50c9f2
        }
Packit Service 50c9f2
        break;
Packit Service 50c9f2
      case Definition::TypeNamespace:
Packit Service 50c9f2
        {
Packit Service 50c9f2
          if (lang==SrcLangExt_Java || lang==SrcLangExt_CSharp)
Packit Service 50c9f2
          {
Packit Service 50c9f2
            name = theTranslator->trPackage(name);
Packit Service 50c9f2
          }
Packit Service 50c9f2
          else if (lang==SrcLangExt_Fortran)
Packit Service 50c9f2
          {
Packit Service 50c9f2
            name.prepend(theTranslator->trModule(TRUE,TRUE)+" ");
Packit Service 50c9f2
          }
Packit Service 50c9f2
          else
Packit Service 50c9f2
          {
Packit Service 50c9f2
            name.prepend(theTranslator->trNamespace(TRUE,TRUE)+" ");
Packit Service 50c9f2
          }
Packit Service 50c9f2
        }
Packit Service 50c9f2
        break;
Packit Service 50c9f2
      case Definition::TypeGroup:
Packit Service 50c9f2
        {
Packit Service 50c9f2
          GroupDef *gd = (GroupDef *)ctx;
Packit Service 50c9f2
          if (gd->groupTitle())
Packit Service 50c9f2
          {
Packit Service 50c9f2
            name = theTranslator->trGroup(TRUE,TRUE)+" "+gd->groupTitle();
Packit Service 50c9f2
          }
Packit Service 50c9f2
          else
Packit Service 50c9f2
          {
Packit Service 50c9f2
            name.prepend(theTranslator->trGroup(TRUE,TRUE)+" ");
Packit Service 50c9f2
          }
Packit Service 50c9f2
        }
Packit Service 50c9f2
        break;
Packit Service 50c9f2
      default:
Packit Service 50c9f2
        break;
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
Packit Service 50c9f2
  int *pIndex = m_url2IdMap.find(baseUrl);
Packit Service 50c9f2
  if (pIndex==0)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    ++m_urlIndex;
Packit Service 50c9f2
    m_url2IdMap.insert(baseUrl,new int(m_urlIndex));
Packit Service 50c9f2
    m_urls.insert(m_urlIndex,new URL(name,url));
Packit Service 50c9f2
  }
Packit Service 50c9f2
  else
Packit Service 50c9f2
  {
Packit Service 50c9f2
    m_urls.insert(*pIndex,new URL(name,url));
Packit Service 50c9f2
  }
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
static int charsToIndex(const char *word)
Packit Service 50c9f2
{
Packit Service 50c9f2
  if (word==0) return -1;
Packit Service 50c9f2
Packit Service 50c9f2
  // Fast string hashing algorithm
Packit Service 50c9f2
  //register ushort h=0;
Packit Service 50c9f2
  //const char *k = word;
Packit Service 50c9f2
  //ushort mask=0xfc00;
Packit Service 50c9f2
  //while ( *k )
Packit Service 50c9f2
  //{
Packit Service 50c9f2
  //  h = (h&mask)^(h<<6)^(*k++);
Packit Service 50c9f2
  //}
Packit Service 50c9f2
  //return h;
Packit Service 50c9f2
Packit Service 50c9f2
  // Simple hashing that allows for substring searching
Packit Service 50c9f2
  uint c1=((uchar *)word)[0];
Packit Service 50c9f2
  if (c1==0) return -1;
Packit Service 50c9f2
  uint c2=((uchar *)word)[1];
Packit Service 50c9f2
  if (c2==0) return -1;
Packit Service 50c9f2
  return c1*256+c2;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
void SearchIndex::addWord(const char *word,bool hiPriority,bool recurse)
Packit Service 50c9f2
{
Packit Service 50c9f2
  static QRegExp nextPart("[_a-z:][A-Z]");
Packit Service 50c9f2
  if (word==0 || word[0]=='\0') return;
Packit Service 50c9f2
  QCString wStr = QCString(word).lower();
Packit Service 50c9f2
  //printf("SearchIndex::addWord(%s,%d) wStr=%s\n",word,hiPriority,wStr.data());
Packit Service 50c9f2
  IndexWord *w = m_words[wStr];
Packit Service 50c9f2
  if (w==0)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    int idx=charsToIndex(wStr);
Packit Service 50c9f2
    //fprintf(stderr,"addWord(%s) at index %d\n",word,idx);
Packit Service 50c9f2
    if (idx<0) return;
Packit Service 50c9f2
    w = new IndexWord(wStr);
Packit Service 50c9f2
    m_index[idx]->append(w);
Packit Service 50c9f2
    m_words.insert(wStr,w);
Packit Service 50c9f2
  }
Packit Service 50c9f2
  w->addUrlIndex(m_urlIndex,hiPriority);
Packit Service 50c9f2
  int i;
Packit Service 50c9f2
  bool found=FALSE;
Packit Service 50c9f2
  if (!recurse) // the first time we check if we can strip the prefix
Packit Service 50c9f2
  {
Packit Service 50c9f2
    i=getPrefixIndex(word);
Packit Service 50c9f2
    if (i>0)
Packit Service 50c9f2
    {
Packit Service 50c9f2
      addWord(word+i,hiPriority,TRUE);
Packit Service 50c9f2
      found=TRUE;
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
  if (!found) // no prefix stripped
Packit Service 50c9f2
  {
Packit Service 50c9f2
    if ((i=nextPart.match(word))>=1)
Packit Service 50c9f2
    {
Packit Service 50c9f2
      addWord(word+i+1,hiPriority,TRUE);
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
void SearchIndex::addWord(const char *word,bool hiPriority)
Packit Service 50c9f2
{
Packit Service 50c9f2
  addWord(word,hiPriority,FALSE);
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
static void writeInt(QFile &f,int index)
Packit Service 50c9f2
{
Packit Service 50c9f2
  f.putch(((uint)index)>>24);
Packit Service 50c9f2
  f.putch((((uint)index)>>16)&0xff);
Packit Service 50c9f2
  f.putch((((uint)index)>>8)&0xff);
Packit Service 50c9f2
  f.putch(((uint)index)&0xff);
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
static void writeString(QFile &f,const char *s)
Packit Service 50c9f2
{
Packit Service 50c9f2
  const char *p = s;
Packit Service 50c9f2
  while (*p) f.putch(*p++);
Packit Service 50c9f2
  f.putch(0);
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
void SearchIndex::write(const char *fileName)
Packit Service 50c9f2
{
Packit Service 50c9f2
  int i;
Packit Service 50c9f2
  int size=4; // for the header
Packit Service 50c9f2
  size+=4*numIndexEntries; // for the index
Packit Service 50c9f2
  int wordsOffset = size;
Packit Service 50c9f2
  // first pass: compute the size of the wordlist
Packit Service 50c9f2
  for (i=0;i
Packit Service 50c9f2
  {
Packit Service 50c9f2
    QList<IndexWord> *wlist = m_index[i];
Packit Service 50c9f2
    if (!wlist->isEmpty())
Packit Service 50c9f2
    {
Packit Service 50c9f2
      QListIterator<IndexWord> iwi(*wlist);
Packit Service 50c9f2
      IndexWord *iw;
Packit Service 50c9f2
      for (iwi.toFirst();(iw=iwi.current());++iwi)
Packit Service 50c9f2
      {
Packit Service 50c9f2
        int ws = iw->word().length()+1;
Packit Service 50c9f2
        size+=ws+4; // word + url info list offset
Packit Service 50c9f2
      }
Packit Service 50c9f2
      size+=1; // zero list terminator
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
Packit Service 50c9f2
  // second pass: compute the offsets in the index
Packit Service 50c9f2
  int indexOffsets[numIndexEntries];
Packit Service 50c9f2
  int offset=wordsOffset;
Packit Service 50c9f2
  for (i=0;i
Packit Service 50c9f2
  {
Packit Service 50c9f2
    QList<IndexWord> *wlist = m_index[i];
Packit Service 50c9f2
    if (!wlist->isEmpty())
Packit Service 50c9f2
    {
Packit Service 50c9f2
      indexOffsets[i]=offset;
Packit Service 50c9f2
      QListIterator<IndexWord> iwi(*wlist);
Packit Service 50c9f2
      IndexWord *iw;
Packit Service 50c9f2
      for (iwi.toFirst();(iw=iwi.current());++iwi)
Packit Service 50c9f2
      {
Packit Service 50c9f2
        offset+= iw->word().length()+1;
Packit Service 50c9f2
        offset+=4; // word + offset to url info array
Packit Service 50c9f2
      }
Packit Service 50c9f2
      offset+=1; // zero list terminator
Packit Service 50c9f2
    }
Packit Service 50c9f2
    else
Packit Service 50c9f2
    {
Packit Service 50c9f2
      indexOffsets[i]=0;
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
  int padding = size;
Packit Service 50c9f2
  size = (size+3)&~;; // round up to 4 byte boundary
Packit Service 50c9f2
  padding = size - padding;
Packit Service 50c9f2
Packit Service 50c9f2
  //int statsOffset = size;
Packit Service 50c9f2
  //IndexWord *iw;
Packit Service 50c9f2
  int *wordStatOffsets = new int[m_words.count()];
Packit Service 50c9f2
Packit Service 50c9f2
  int count=0;
Packit Service 50c9f2
Packit Service 50c9f2
  // third pass: compute offset to stats info for each word
Packit Service 50c9f2
  for (i=0;i
Packit Service 50c9f2
  {
Packit Service 50c9f2
    QList<IndexWord> *wlist = m_index[i];
Packit Service 50c9f2
    if (!wlist->isEmpty())
Packit Service 50c9f2
    {
Packit Service 50c9f2
      QListIterator<IndexWord> iwi(*wlist);
Packit Service 50c9f2
      IndexWord *iw;
Packit Service 50c9f2
      for (iwi.toFirst();(iw=iwi.current());++iwi)
Packit Service 50c9f2
      {
Packit Service 50c9f2
        //printf("wordStatOffsets[%d]=%d\n",count,size);
Packit Service 50c9f2
        wordStatOffsets[count++] = size;
Packit Service 50c9f2
        size+=4+iw->urls().count()*8; // count + (url_index,freq) per url
Packit Service 50c9f2
      }
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
  int *urlOffsets = new int[m_urls.count()];
Packit Service 50c9f2
  //int urlsOffset = size;
Packit Service 50c9f2
  QIntDictIterator<URL> udi(m_urls);
Packit Service 50c9f2
  URL *url;
Packit Service 50c9f2
  for (udi.toFirst();(url=udi.current());++udi)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    urlOffsets[udi.currentKey()]=size;
Packit Service 50c9f2
    size+=url->name.length()+1+
Packit Service 50c9f2
          url->url.length()+1;
Packit Service 50c9f2
  }
Packit Service 50c9f2
  //printf("Total size %x bytes (word=%x stats=%x urls=%x)\n",size,wordsOffset,statsOffset,urlsOffset);
Packit Service 50c9f2
  QFile f(fileName);
Packit Service 50c9f2
  if (f.open(IO_WriteOnly))
Packit Service 50c9f2
  {
Packit Service 50c9f2
    // write header
Packit Service 50c9f2
    f.putch('D'); f.putch('O'); f.putch('X'); f.putch('S');
Packit Service 50c9f2
    // write index
Packit Service 50c9f2
    for (i=0;i
Packit Service 50c9f2
    {
Packit Service 50c9f2
      writeInt(f,indexOffsets[i]);
Packit Service 50c9f2
    }
Packit Service 50c9f2
    // write word lists
Packit Service 50c9f2
    count=0;
Packit Service 50c9f2
    for (i=0;i
Packit Service 50c9f2
    {
Packit Service 50c9f2
      QList<IndexWord> *wlist = m_index[i];
Packit Service 50c9f2
      if (!wlist->isEmpty())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        QListIterator<IndexWord> iwi(*wlist);
Packit Service 50c9f2
        IndexWord *iw;
Packit Service 50c9f2
        for (iwi.toFirst();(iw=iwi.current());++iwi)
Packit Service 50c9f2
        {
Packit Service 50c9f2
          writeString(f,iw->word());
Packit Service 50c9f2
          writeInt(f,wordStatOffsets[count++]);
Packit Service 50c9f2
        }
Packit Service 50c9f2
        f.putch(0);
Packit Service 50c9f2
      }
Packit Service 50c9f2
    }
Packit Service 50c9f2
    // write extra padding bytes
Packit Service 50c9f2
    for (i=0;i
Packit Service 50c9f2
    // write word statistics
Packit Service 50c9f2
    for (i=0;i
Packit Service 50c9f2
    {
Packit Service 50c9f2
      QList<IndexWord> *wlist = m_index[i];
Packit Service 50c9f2
      if (!wlist->isEmpty())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        QListIterator<IndexWord> iwi(*wlist);
Packit Service 50c9f2
        IndexWord *iw;
Packit Service 50c9f2
        for (iwi.toFirst();(iw=iwi.current());++iwi)
Packit Service 50c9f2
        {
Packit Service 50c9f2
          int numUrls = iw->urls().count();
Packit Service 50c9f2
          writeInt(f,numUrls);
Packit Service 50c9f2
          QIntDictIterator<URLInfo> uli(iw->urls());
Packit Service 50c9f2
          URLInfo *ui;
Packit Service 50c9f2
          for (uli.toFirst();(ui=uli.current());++uli)
Packit Service 50c9f2
          {
Packit Service 50c9f2
            writeInt(f,urlOffsets[ui->urlIdx]);
Packit Service 50c9f2
            writeInt(f,ui->freq);
Packit Service 50c9f2
          }
Packit Service 50c9f2
        }
Packit Service 50c9f2
      }
Packit Service 50c9f2
    }
Packit Service 50c9f2
    // write urls
Packit Service 50c9f2
    QIntDictIterator<URL> udi(m_urls);
Packit Service 50c9f2
    URL *url;
Packit Service 50c9f2
    for (udi.toFirst();(url=udi.current());++udi)
Packit Service 50c9f2
    {
Packit Service 50c9f2
      writeString(f,url->name);
Packit Service 50c9f2
      writeString(f,url->url);
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
Packit Service 50c9f2
  delete[] urlOffsets;
Packit Service 50c9f2
  delete[] wordStatOffsets;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
Packit Service 50c9f2
//---------------------------------------------------------------------------
Packit Service 50c9f2
// the following part is for writing an external search index
Packit Service 50c9f2
Packit Service 50c9f2
struct SearchDocEntry
Packit Service 50c9f2
{
Packit Service 50c9f2
  QCString type;
Packit Service 50c9f2
  QCString name;
Packit Service 50c9f2
  QCString args;
Packit Service 50c9f2
  QCString extId;
Packit Service 50c9f2
  QCString url;
Packit Service 50c9f2
  GrowBuf  importantText;
Packit Service 50c9f2
  GrowBuf  normalText;
Packit Service 50c9f2
};
Packit Service 50c9f2
Packit Service 50c9f2
struct SearchIndexExternal::Private
Packit Service 50c9f2
{
Packit Service 50c9f2
  Private() : docEntries(12251) {}
Packit Service 50c9f2
  SDict<SearchDocEntry> docEntries;
Packit Service 50c9f2
  SearchDocEntry *current;
Packit Service 50c9f2
};
Packit Service 50c9f2
Packit Service 50c9f2
SearchIndexExternal::SearchIndexExternal() : SearchIndexIntf(External)
Packit Service 50c9f2
{
Packit Service 50c9f2
  p = new SearchIndexExternal::Private;
Packit Service 50c9f2
  p->docEntries.setAutoDelete(TRUE);
Packit Service 50c9f2
  p->current=0;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
SearchIndexExternal::~SearchIndexExternal()
Packit Service 50c9f2
{
Packit Service 50c9f2
  //printf("p->docEntries.count()=%d\n",p->docEntries.count());
Packit Service 50c9f2
  delete p;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
static QCString definitionToName(Definition *ctx)
Packit Service 50c9f2
{
Packit Service 50c9f2
  if (ctx && ctx->definitionType()==Definition::TypeMember)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    MemberDef *md = (MemberDef*)ctx;
Packit Service 50c9f2
    if (md->isFunction())
Packit Service 50c9f2
      return "function";
Packit Service 50c9f2
    else if (md->isSlot())
Packit Service 50c9f2
      return "slot";
Packit Service 50c9f2
    else if (md->isSignal())
Packit Service 50c9f2
      return "signal";
Packit Service 50c9f2
    else if (md->isVariable())
Packit Service 50c9f2
      return "variable";
Packit Service 50c9f2
    else if (md->isTypedef())
Packit Service 50c9f2
      return "typedef";
Packit Service 50c9f2
    else if (md->isEnumerate())
Packit Service 50c9f2
      return "enum";
Packit Service 50c9f2
    else if (md->isEnumValue())
Packit Service 50c9f2
      return "enumvalue";
Packit Service 50c9f2
    else if (md->isProperty())
Packit Service 50c9f2
      return "property";
Packit Service 50c9f2
    else if (md->isEvent())
Packit Service 50c9f2
      return "event";
Packit Service 50c9f2
    else if (md->isRelated() || md->isForeign())
Packit Service 50c9f2
      return "related";
Packit Service 50c9f2
    else if (md->isFriend())
Packit Service 50c9f2
      return "friend";
Packit Service 50c9f2
    else if (md->isDefine())
Packit Service 50c9f2
      return "define";
Packit Service 50c9f2
  }
Packit Service 50c9f2
  else if (ctx)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    switch(ctx->definitionType())
Packit Service 50c9f2
    {
Packit Service 50c9f2
      case Definition::TypeClass:
Packit Service 50c9f2
        return ((ClassDef*)ctx)->compoundTypeString();
Packit Service 50c9f2
      case Definition::TypeFile:
Packit Service 50c9f2
        return "file";
Packit Service 50c9f2
      case Definition::TypeNamespace:
Packit Service 50c9f2
        return "namespace";
Packit Service 50c9f2
      case Definition::TypeGroup:
Packit Service 50c9f2
        return "group";
Packit Service 50c9f2
      case Definition::TypePackage:
Packit Service 50c9f2
        return "package";
Packit Service 50c9f2
      case Definition::TypePage:
Packit Service 50c9f2
        return "page";
Packit Service 50c9f2
      case Definition::TypeDir:
Packit Service 50c9f2
        return "dir";
Packit Service 50c9f2
      default:
Packit Service 50c9f2
        break;
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
  return "unknown";
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
void SearchIndexExternal::setCurrentDoc(Definition *ctx,const char *anchor,bool isSourceFile)
Packit Service 50c9f2
{
Packit Service 50c9f2
  QCString extId = stripPath(Config_getString(EXTERNAL_SEARCH_ID));
Packit Service 50c9f2
  QCString baseName = isSourceFile ? ((FileDef*)ctx)->getSourceFileBase() : ctx->getOutputFileBase();
Packit Service 50c9f2
  QCString url = baseName + Doxygen::htmlFileExtension;
Packit Service 50c9f2
  if (anchor) url+=QCString("#")+anchor;
Packit Service 50c9f2
  QCString key = extId+";"+url;
Packit Service 50c9f2
Packit Service 50c9f2
  p->current = p->docEntries.find(key);
Packit Service 50c9f2
  //printf("setCurrentDoc(url=%s,isSourceFile=%d) current=%p\n",url.data(),isSourceFile,p->current);
Packit Service 50c9f2
  if (!p->current)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    SearchDocEntry *e = new SearchDocEntry;
Packit Service 50c9f2
    e->type = isSourceFile ? QCString("source") : definitionToName(ctx);
Packit Service 50c9f2
    e->name = ctx->qualifiedName();
Packit Service 50c9f2
    if (ctx->definitionType()==Definition::TypeMember)
Packit Service 50c9f2
    {
Packit Service 50c9f2
      e->args = ((MemberDef*)ctx)->argsString();
Packit Service 50c9f2
    }
Packit Service 50c9f2
    e->extId = extId;
Packit Service 50c9f2
    e->url  = url;
Packit Service 50c9f2
    p->current = e;
Packit Service 50c9f2
    p->docEntries.append(key,e);
Packit Service 50c9f2
    //printf("searchIndexExt %s : %s\n",e->name.data(),e->url.data());
Packit Service 50c9f2
  }
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
void SearchIndexExternal::addWord(const char *word,bool hiPriority)
Packit Service 50c9f2
{
Packit Service 50c9f2
  if (word==0 || !isId(*word) || p->current==0) return;
Packit Service 50c9f2
  GrowBuf *pText = hiPriority ? &p->current->importantText : &p->current->normalText;
Packit Service 50c9f2
  if (pText->getPos()>0) pText->addChar(' ');
Packit Service 50c9f2
  pText->addStr(word);
Packit Service 50c9f2
  //printf("addWord %s\n",word);
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
void SearchIndexExternal::write(const char *fileName)
Packit Service 50c9f2
{
Packit Service 50c9f2
  QFile f(fileName);
Packit Service 50c9f2
  if (f.open(IO_WriteOnly))
Packit Service 50c9f2
  {
Packit Service 50c9f2
    FTextStream t(&f);
Packit Service 50c9f2
    t << "" << endl;
Packit Service 50c9f2
    t << "<add>" << endl;
Packit Service 50c9f2
    SDict<SearchDocEntry>::Iterator it(p->docEntries);
Packit Service 50c9f2
    SearchDocEntry *doc;
Packit Service 50c9f2
    for (it.toFirst();(doc=it.current());++it)
Packit Service 50c9f2
    {
Packit Service 50c9f2
      doc->normalText.addChar(0);    // make sure buffer ends with a 0 terminator
Packit Service 50c9f2
      doc->importantText.addChar(0); // make sure buffer ends with a 0 terminator
Packit Service 50c9f2
      t << "  <doc>" << endl;
Packit Service 50c9f2
      t << "    <field name=\"type\">"     << doc->type << "</field>" << endl;
Packit Service 50c9f2
      t << "    <field name=\"name\">"     << convertToXML(doc->name) << "</field>" << endl;
Packit Service 50c9f2
      if (!doc->args.isEmpty())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        t << "    <field name=\"args\">"     << convertToXML(doc->args) << "</field>" << endl;
Packit Service 50c9f2
      }
Packit Service 50c9f2
      if (!doc->extId.isEmpty())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        t << "    <field name=\"tag\">"      << convertToXML(doc->extId)  << "</field>" << endl;
Packit Service 50c9f2
      }
Packit Service 50c9f2
      t << "    <field name=\"url\">"      << convertToXML(doc->url)  << "</field>" << endl;
Packit Service 50c9f2
      t << "    <field name=\"keywords\">" << convertToXML(doc->importantText.get())  << "</field>" << endl;
Packit Service 50c9f2
      t << "    <field name=\"text\">"     << convertToXML(doc->normalText.get())     << "</field>" << endl;
Packit Service 50c9f2
      t << "  </doc>" << endl;
Packit Service 50c9f2
    }
Packit Service 50c9f2
    t << "</add>" << endl;
Packit Service 50c9f2
  }
Packit Service 50c9f2
  else
Packit Service 50c9f2
  {
Packit Service 50c9f2
    err("Failed to open file %s for writing!\n",fileName);
Packit Service 50c9f2
  }
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
//---------------------------------------------------------------------------
Packit Service 50c9f2
// the following part is for the javascript based search engine
Packit Service 50c9f2
Packit Service 50c9f2
#include "memberdef.h"
Packit Service 50c9f2
#include "namespacedef.h"
Packit Service 50c9f2
#include "pagedef.h"
Packit Service 50c9f2
#include "classdef.h"
Packit Service 50c9f2
#include "filedef.h"
Packit Service 50c9f2
#include "language.h"
Packit Service 50c9f2
#include "doxygen.h"
Packit Service 50c9f2
#include "message.h"
Packit Service 50c9f2
Packit Service 50c9f2
static SearchIndexInfo g_searchIndexInfo[NUM_SEARCH_INDICES];
Packit Service 50c9f2
Packit Service 50c9f2
static void addMemberToSearchIndex(MemberDef *md)
Packit Service 50c9f2
{
Packit Service 50c9f2
  static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS);
Packit Service 50c9f2
  bool isLinkable = md->isLinkable();
Packit Service 50c9f2
  ClassDef *cd=0;
Packit Service 50c9f2
  NamespaceDef *nd=0;
Packit Service 50c9f2
  FileDef *fd=0;
Packit Service 50c9f2
  GroupDef *gd=0;
Packit Service 50c9f2
  if (isLinkable &&
Packit Service 50c9f2
      (
Packit Service 50c9f2
       ((cd=md->getClassDef()) && cd->isLinkable() && cd->templateMaster()==0) ||
Packit Service 50c9f2
       ((gd=md->getGroupDef()) && gd->isLinkable())
Packit Service 50c9f2
      )
Packit Service 50c9f2
     )
Packit Service 50c9f2
  {
Packit Service 50c9f2
    QCString n = md->name();
Packit Service 50c9f2
    if (!n.isEmpty())
Packit Service 50c9f2
    {
Packit Service 50c9f2
      uint letter = getUtf8CodeToLower(n,0);
Packit Service 50c9f2
      bool isFriendToHide = hideFriendCompounds &&
Packit Service 50c9f2
        (QCString(md->typeString())=="friend class" ||
Packit Service 50c9f2
         QCString(md->typeString())=="friend struct" ||
Packit Service 50c9f2
         QCString(md->typeString())=="friend union");
Packit Service 50c9f2
      if (!(md->isFriend() && isFriendToHide))
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
      if (md->isFunction() || md->isSlot() || md->isSignal())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].symbolList.append(letter,md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
      else if (md->isVariable())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_VARIABLES].symbolList.append(letter,md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
      else if (md->isTypedef())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].symbolList.append(letter,md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
      else if (md->isEnumerate())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_ENUMS].symbolList.append(letter,md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
      else if (md->isEnumValue())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].symbolList.append(letter,md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
      else if (md->isProperty())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_PROPERTIES].symbolList.append(letter,md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
      else if (md->isEvent())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_EVENTS].symbolList.append(letter,md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
      else if (md->isRelated() || md->isForeign() ||
Packit Service 50c9f2
               (md->isFriend() && !isFriendToHide))
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_RELATED].symbolList.append(letter,md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
  else if (isLinkable &&
Packit Service 50c9f2
      (((nd=md->getNamespaceDef()) && nd->isLinkable()) ||
Packit Service 50c9f2
       ((fd=md->getFileDef())      && fd->isLinkable())
Packit Service 50c9f2
      )
Packit Service 50c9f2
     )
Packit Service 50c9f2
  {
Packit Service 50c9f2
    QCString n = md->name();
Packit Service 50c9f2
    if (!n.isEmpty())
Packit Service 50c9f2
    {
Packit Service 50c9f2
      uint letter = getUtf8CodeToLower(n,0);
Packit Service 50c9f2
      g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,md);
Packit Service 50c9f2
Packit Service 50c9f2
      if (md->isFunction())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].symbolList.append(letter,md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
      else if (md->isVariable())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_VARIABLES].symbolList.append(letter,md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
      else if (md->isTypedef())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].symbolList.append(letter,md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
      else if (md->isEnumerate())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_ENUMS].symbolList.append(letter,md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
      else if (md->isEnumValue())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].symbolList.append(letter,md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
      else if (md->isDefine())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_DEFINES].symbolList.append(letter,md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
// see also function convertToId() in search.js, which should match in
Packit Service 50c9f2
// behaviour
Packit Service 50c9f2
static QCString searchId(const QCString &s)
Packit Service 50c9f2
{
Packit Service 50c9f2
  int c;
Packit Service 50c9f2
  uint i;
Packit Service 50c9f2
  QCString result;
Packit Service 50c9f2
  for (i=0;i
Packit Service 50c9f2
  {
Packit Service 50c9f2
    c=s.at(i);
Packit Service 50c9f2
    if (c>0x7f || c<0) // part of multibyte character
Packit Service 50c9f2
    {
Packit Service 50c9f2
      result+=(char)c;
Packit Service 50c9f2
    }
Packit Service 50c9f2
    else if (isalnum(c)) // simply alpha numerical character
Packit Service 50c9f2
    {
Packit Service 50c9f2
      result+=(char)tolower(c);
Packit Service 50c9f2
    }
Packit Service 50c9f2
    else // other 'unprintable' characters
Packit Service 50c9f2
    {
Packit Service 50c9f2
      char val[4];
Packit Service 50c9f2
      sprintf(val,"_%02x",(uchar)c);
Packit Service 50c9f2
      result+=val;
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
  return result;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
void createJavascriptSearchIndex()
Packit Service 50c9f2
{
Packit Service 50c9f2
  // set index names
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_ALL].name        = "all";
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_CLASSES].name    = "classes";
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_NAMESPACES].name = "namespaces";
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_FILES].name      = "files";
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].name  = "functions";
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_VARIABLES].name  = "variables";
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].name   = "typedefs";
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_ENUMS].name      = "enums";
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].name = "enumvalues";
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_PROPERTIES].name = "properties";
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_EVENTS].name     = "events";
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_RELATED].name    = "related";
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_DEFINES].name    = "defines";
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_GROUPS].name     = "groups";
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_PAGES].name      = "pages";
Packit Service 50c9f2
Packit Service 50c9f2
  // set index texts
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_ALL].text        = theTranslator->trAll();
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_CLASSES].text    = theTranslator->trClasses();
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_NAMESPACES].text = theTranslator->trNamespace(TRUE,FALSE);
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_FILES].text      = theTranslator->trFile(TRUE,FALSE);
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].text  = theTranslator->trFunctions();
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_VARIABLES].text  = theTranslator->trVariables();
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].text   = theTranslator->trTypedefs();
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_ENUMS].text      = theTranslator->trEnumerations();
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].text = theTranslator->trEnumerationValues();
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_PROPERTIES].text = theTranslator->trProperties();
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_EVENTS].text     = theTranslator->trEvents();
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_RELATED].text    = theTranslator->trFriends();
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_DEFINES].text    = theTranslator->trDefines();
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_GROUPS].text     = theTranslator->trGroup(TRUE,FALSE);
Packit Service 50c9f2
  g_searchIndexInfo[SEARCH_INDEX_PAGES].text      = theTranslator->trPage(TRUE,FALSE);
Packit Service 50c9f2
Packit Service 50c9f2
  // add symbols to letter -> symbol list map
Packit Service 50c9f2
Packit Service 50c9f2
  // index classes
Packit Service 50c9f2
  ClassSDict::Iterator cli(*Doxygen::classSDict);
Packit Service 50c9f2
  ClassDef *cd;
Packit Service 50c9f2
  for (;(cd=cli.current());++cli)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    uint letter = getUtf8CodeToLower(cd->localName(),0);
Packit Service 50c9f2
    if (cd->isLinkable() && isId(letter))
Packit Service 50c9f2
    {
Packit Service 50c9f2
      g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,cd);
Packit Service 50c9f2
      g_searchIndexInfo[SEARCH_INDEX_CLASSES].symbolList.append(letter,cd);
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
Packit Service 50c9f2
  // index namespaces
Packit Service 50c9f2
  NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
Packit Service 50c9f2
  NamespaceDef *nd;
Packit Service 50c9f2
  for (;(nd=nli.current());++nli)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    uint letter = getUtf8CodeToLower(nd->name(),0);
Packit Service 50c9f2
    if (nd->isLinkable() && isId(letter))
Packit Service 50c9f2
    {
Packit Service 50c9f2
      g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,nd);
Packit Service 50c9f2
      g_searchIndexInfo[SEARCH_INDEX_NAMESPACES].symbolList.append(letter,nd);
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
Packit Service 50c9f2
  // index files
Packit Service 50c9f2
  FileNameListIterator fnli(*Doxygen::inputNameList);
Packit Service 50c9f2
  FileName *fn;
Packit Service 50c9f2
  for (;(fn=fnli.current());++fnli)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    FileNameIterator fni(*fn);
Packit Service 50c9f2
    FileDef *fd;
Packit Service 50c9f2
    for (;(fd=fni.current());++fni)
Packit Service 50c9f2
    {
Packit Service 50c9f2
      uint letter = getUtf8CodeToLower(fd->name(),0);
Packit Service 50c9f2
      if (fd->isLinkable() && isId(letter))
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,fd);
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_FILES].symbolList.append(letter,fd);
Packit Service 50c9f2
      }
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
Packit Service 50c9f2
  // index class members
Packit Service 50c9f2
  {
Packit Service 50c9f2
    MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict);
Packit Service 50c9f2
    MemberName *mn;
Packit Service 50c9f2
    // for each member name
Packit Service 50c9f2
    for (mnli.toFirst();(mn=mnli.current());++mnli)
Packit Service 50c9f2
    {
Packit Service 50c9f2
      MemberDef *md;
Packit Service 50c9f2
      MemberNameIterator mni(*mn);
Packit Service 50c9f2
      // for each member definition
Packit Service 50c9f2
      for (mni.toFirst();(md=mni.current());++mni)
Packit Service 50c9f2
      {
Packit Service 50c9f2
        addMemberToSearchIndex(md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
Packit Service 50c9f2
  // index file/namespace members
Packit Service 50c9f2
  {
Packit Service 50c9f2
    MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict);
Packit Service 50c9f2
    MemberName *mn;
Packit Service 50c9f2
    // for each member name
Packit Service 50c9f2
    for (fnli.toFirst();(mn=fnli.current());++fnli)
Packit Service 50c9f2
    {
Packit Service 50c9f2
      MemberDef *md;
Packit Service 50c9f2
      MemberNameIterator mni(*mn);
Packit Service 50c9f2
      // for each member definition
Packit Service 50c9f2
      for (mni.toFirst();(md=mni.current());++mni)
Packit Service 50c9f2
      {
Packit Service 50c9f2
        addMemberToSearchIndex(md);
Packit Service 50c9f2
      }
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
Packit Service 50c9f2
  // index groups
Packit Service 50c9f2
  GroupSDict::Iterator gli(*Doxygen::groupSDict);
Packit Service 50c9f2
  GroupDef *gd;
Packit Service 50c9f2
  for (gli.toFirst();(gd=gli.current());++gli)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    if (gd->isLinkable())
Packit Service 50c9f2
    {
Packit Service 50c9f2
      QCString title = gd->groupTitle();
Packit Service 50c9f2
      if (!title.isEmpty()) // TODO: able searching for all word in the title
Packit Service 50c9f2
      {
Packit Service 50c9f2
        uchar charCode = title.at(0);
Packit Service 50c9f2
        uint letter = charCode<128 ? tolower(charCode) : charCode;
Packit Service 50c9f2
        if (isId(letter))
Packit Service 50c9f2
        {
Packit Service 50c9f2
          g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,gd);
Packit Service 50c9f2
          g_searchIndexInfo[SEARCH_INDEX_GROUPS].symbolList.append(letter,gd);
Packit Service 50c9f2
        }
Packit Service 50c9f2
      }
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
Packit Service 50c9f2
  // index pages
Packit Service 50c9f2
  PageSDict::Iterator pdi(*Doxygen::pageSDict);
Packit Service 50c9f2
  PageDef *pd=0;
Packit Service 50c9f2
  for (pdi.toFirst();(pd=pdi.current());++pdi)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    if (pd->isLinkable())
Packit Service 50c9f2
    {
Packit Service 50c9f2
      QCString title = pd->title();
Packit Service 50c9f2
      if (!title.isEmpty())
Packit Service 50c9f2
      {
Packit Service 50c9f2
        uchar charCode = title.at(0);
Packit Service 50c9f2
        uint letter = charCode<128 ? tolower(charCode) : charCode;
Packit Service 50c9f2
        if (isId(letter))
Packit Service 50c9f2
        {
Packit Service 50c9f2
          g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,pd);
Packit Service 50c9f2
          g_searchIndexInfo[SEARCH_INDEX_PAGES].symbolList.append(letter,pd);
Packit Service 50c9f2
        }
Packit Service 50c9f2
      }
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
  if (Doxygen::mainPage)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    QCString title = Doxygen::mainPage->title();
Packit Service 50c9f2
    if (!title.isEmpty())
Packit Service 50c9f2
    {
Packit Service 50c9f2
      uchar charCode = title.at(0);
Packit Service 50c9f2
      uint letter = charCode<128 ? tolower(charCode) : charCode;
Packit Service 50c9f2
      if (isId(letter))
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,Doxygen::mainPage);
Packit Service 50c9f2
        g_searchIndexInfo[SEARCH_INDEX_PAGES].symbolList.append(letter,Doxygen::mainPage);
Packit Service 50c9f2
      }
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
Packit Service 50c9f2
  // sort all lists
Packit Service 50c9f2
  int i;
Packit Service 50c9f2
  for (i=0;i
Packit Service 50c9f2
  {
Packit Service 50c9f2
    SIntDict<SearchIndexList>::Iterator it(g_searchIndexInfo[i].symbolList);
Packit Service 50c9f2
    SearchIndexList *sl;
Packit Service 50c9f2
    for (it.toFirst();(sl=it.current());++it)
Packit Service 50c9f2
    {
Packit Service 50c9f2
      sl->sort();
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
void writeJavascriptSearchIndex()
Packit Service 50c9f2
{
Packit Service 50c9f2
  int i;
Packit Service 50c9f2
  // write index files
Packit Service 50c9f2
  QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
Packit Service 50c9f2
Packit Service 50c9f2
  for (i=0;i
Packit Service 50c9f2
  {
Packit Service 50c9f2
    SIntDict<SearchIndexList>::Iterator it(g_searchIndexInfo[i].symbolList);
Packit Service 50c9f2
    SearchIndexList *sl;
Packit Service 50c9f2
    int p=0;
Packit Service 50c9f2
    for (it.toFirst();(sl=it.current());++it,++p) // for each letter
Packit Service 50c9f2
    {
Packit Service 50c9f2
      QCString baseName;
Packit Service 50c9f2
      baseName.sprintf("%s_%x",g_searchIndexInfo[i].name.data(),p);
Packit Service 50c9f2
Packit Service 50c9f2
      QCString fileName = searchDirName + "/"+baseName+".html";
Packit Service 50c9f2
      QCString dataFileName = searchDirName + "/"+baseName+".js";
Packit Service 50c9f2
Packit Service 50c9f2
      QFile outFile(fileName);
Packit Service 50c9f2
      QFile dataOutFile(dataFileName);
Packit Service 50c9f2
      if (outFile.open(IO_WriteOnly) && dataOutFile.open(IO_WriteOnly))
Packit Service 50c9f2
      {
Packit Service 50c9f2
        {
Packit Service 50c9f2
          FTextStream t(&outFile);
Packit Service 50c9f2
Packit Service 50c9f2
          t << "
Packit Service 50c9f2
            " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl;
Packit Service 50c9f2
          t << "<html><head><title></title>" << endl;
Packit Service 50c9f2
          t << "<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>" << endl;
Packit Service 50c9f2
          t << "<meta name=\"generator\" content=\"Doxygen " << versionString << "\"/>" << endl;
Packit Service 50c9f2
          t << "<link rel=\"stylesheet\" type=\"text/css\" href=\"search.css\"/>" << endl;
Packit Service 50c9f2
          t << "<script type=\"text/javascript\" src=\"" << baseName << ".js\"></script>" << endl;
Packit Service 50c9f2
          t << "<script type=\"text/javascript\" src=\"search.js\"></script>" << endl;
Packit Service 50c9f2
          t << "</head>" << endl;
Packit Service 50c9f2
          t << "<body class=\"SRPage\">" << endl;
Packit Service 50c9f2
          t << "
" << endl;
Packit Service 50c9f2
          t << "
" << theTranslator->trLoading() << "
" << endl;
Packit Service 50c9f2
          t << "
" << endl; // here the results will be inserted
Packit Service 50c9f2
          t << "<script type=\"text/javascript\">
Packit Service 50c9f2
					t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n";
Packit Service 50c9f2
          t << "createResults();" << endl; // this function will insert the results
Packit Service 50c9f2
					t << "/* @license-end */\n";
Packit Service 50c9f2
          t << "--></script>" << endl;
Packit Service 50c9f2
          t << "
"
Packit Service 50c9f2
            << theTranslator->trSearching() << "" << endl;
Packit Service 50c9f2
          t << "
"
Packit Service 50c9f2
            << theTranslator->trNoMatches() << "" << endl;
Packit Service 50c9f2
Packit Service 50c9f2
          t << "<script type=\"text/javascript\">
Packit Service 50c9f2
					t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n";
Packit Service 50c9f2
          t << "document.getElementById(\"Loading\").style.display=\"none\";" << endl;
Packit Service 50c9f2
          t << "document.getElementById(\"NoMatches\").style.display=\"none\";" << endl;
Packit Service 50c9f2
          t << "var searchResults = new SearchResults(\"searchResults\");" << endl;
Packit Service 50c9f2
          t << "searchResults.Search();" << endl;
Packit Service 50c9f2
					t << "/* @license-end */\n";
Packit Service 50c9f2
          t << "--></script>" << endl;
Packit Service 50c9f2
          t << "" << endl; // SRIndex
Packit Service 50c9f2
          t << "</body>" << endl;
Packit Service 50c9f2
          t << "</html>" << endl;
Packit Service 50c9f2
        }
Packit Service 50c9f2
        FTextStream ti(&dataOutFile);
Packit Service 50c9f2
Packit Service 50c9f2
        ti << "var searchData=" << endl;
Packit Service 50c9f2
        // format
Packit Service 50c9f2
        // searchData[] = array of items
Packit Service 50c9f2
        // searchData[x][0] = id
Packit Service 50c9f2
        // searchData[x][1] = [ name + child1 + child2 + .. ]
Packit Service 50c9f2
        // searchData[x][1][0] = name as shown
Packit Service 50c9f2
        // searchData[x][1][y+1] = info for child y
Packit Service 50c9f2
        // searchData[x][1][y+1][0] = url
Packit Service 50c9f2
        // searchData[x][1][y+1][1] = 1 => target="_parent"
Packit Service 50c9f2
        // searchData[x][1][y+1][2] = scope
Packit Service 50c9f2
Packit Service 50c9f2
        ti << "[" << endl;
Packit Service 50c9f2
        bool firstEntry=TRUE;
Packit Service 50c9f2
Packit Service 50c9f2
        SDict<SearchDefinitionList>::Iterator li(*sl);
Packit Service 50c9f2
        SearchDefinitionList *dl;
Packit Service 50c9f2
        int itemCount=0;
Packit Service 50c9f2
        for (li.toFirst();(dl=li.current());++li)
Packit Service 50c9f2
        {
Packit Service 50c9f2
          Definition *d = dl->getFirst();
Packit Service 50c9f2
Packit Service 50c9f2
          if (!firstEntry)
Packit Service 50c9f2
          {
Packit Service 50c9f2
            ti << "," << endl;
Packit Service 50c9f2
          }
Packit Service 50c9f2
          firstEntry=FALSE;
Packit Service 50c9f2
Packit Service 50c9f2
          ti << "  ['" << dl->id() << "',['" << convertToXML(dl->name()) << "',[";
Packit Service 50c9f2
Packit Service 50c9f2
          if (dl->count()==1) // item with a unique name
Packit Service 50c9f2
          {
Packit Service 50c9f2
            MemberDef  *md   = 0;
Packit Service 50c9f2
            bool isMemberDef = d->definitionType()==Definition::TypeMember;
Packit Service 50c9f2
            if (isMemberDef) md = (MemberDef*)d;
Packit Service 50c9f2
            QCString anchor = d->anchor();
Packit Service 50c9f2
Packit Service 50c9f2
            ti << "'" << externalRef("../",d->getReference(),TRUE)
Packit Service 50c9f2
              << d->getOutputFileBase() << Doxygen::htmlFileExtension;
Packit Service 50c9f2
            if (!anchor.isEmpty())
Packit Service 50c9f2
            {
Packit Service 50c9f2
              ti << "#" << anchor;
Packit Service 50c9f2
            }
Packit Service 50c9f2
            ti << "',";
Packit Service 50c9f2
Packit Service 50c9f2
            static bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
Packit Service 50c9f2
            if (!extLinksInWindow || d->getReference().isEmpty())
Packit Service 50c9f2
            {
Packit Service 50c9f2
              ti << "1,";
Packit Service 50c9f2
            }
Packit Service 50c9f2
            else
Packit Service 50c9f2
            {
Packit Service 50c9f2
              ti << "0,";
Packit Service 50c9f2
            }
Packit Service 50c9f2
Packit Service 50c9f2
            if (d->getOuterScope()!=Doxygen::globalScope)
Packit Service 50c9f2
            {
Packit Service 50c9f2
              ti << "'" << convertToXML(d->getOuterScope()->name()) << "'";
Packit Service 50c9f2
            }
Packit Service 50c9f2
            else if (md)
Packit Service 50c9f2
            {
Packit Service 50c9f2
              FileDef *fd = md->getBodyDef();
Packit Service 50c9f2
              if (fd==0) fd = md->getFileDef();
Packit Service 50c9f2
              if (fd)
Packit Service 50c9f2
              {
Packit Service 50c9f2
                ti << "'" << convertToXML(fd->localName()) << "'";
Packit Service 50c9f2
              }
Packit Service 50c9f2
            }
Packit Service 50c9f2
            else
Packit Service 50c9f2
            {
Packit Service 50c9f2
              ti << "''";
Packit Service 50c9f2
            }
Packit Service 50c9f2
            ti << "]]";
Packit Service 50c9f2
          }
Packit Service 50c9f2
          else // multiple items with the same name
Packit Service 50c9f2
          {
Packit Service 50c9f2
            QListIterator<Definition> di(*dl);
Packit Service 50c9f2
            bool overloadedFunction = FALSE;
Packit Service 50c9f2
            Definition *prevScope = 0;
Packit Service 50c9f2
            int childCount=0;
Packit Service 50c9f2
            for (di.toFirst();(d=di.current());)
Packit Service 50c9f2
            {
Packit Service 50c9f2
              ++di;
Packit Service 50c9f2
              Definition *scope     = d->getOuterScope();
Packit Service 50c9f2
              Definition *next      = di.current();
Packit Service 50c9f2
              Definition *nextScope = 0;
Packit Service 50c9f2
              MemberDef  *md        = 0;
Packit Service 50c9f2
              bool isMemberDef = d->definitionType()==Definition::TypeMember;
Packit Service 50c9f2
              if (isMemberDef) md = (MemberDef*)d;
Packit Service 50c9f2
              if (next) nextScope = next->getOuterScope();
Packit Service 50c9f2
              QCString anchor = d->anchor();
Packit Service 50c9f2
Packit Service 50c9f2
              if (childCount>0)
Packit Service 50c9f2
              {
Packit Service 50c9f2
                ti << "],[";
Packit Service 50c9f2
              }
Packit Service 50c9f2
              ti << "'" << externalRef("../",d->getReference(),TRUE)
Packit Service 50c9f2
                << d->getOutputFileBase() << Doxygen::htmlFileExtension;
Packit Service 50c9f2
              if (!anchor.isEmpty())
Packit Service 50c9f2
              {
Packit Service 50c9f2
                ti << "#" << anchor;
Packit Service 50c9f2
              }
Packit Service 50c9f2
              ti << "',";
Packit Service 50c9f2
Packit Service 50c9f2
              static bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
Packit Service 50c9f2
              if (!extLinksInWindow || d->getReference().isEmpty())
Packit Service 50c9f2
              {
Packit Service 50c9f2
                ti << "1,";
Packit Service 50c9f2
              }
Packit Service 50c9f2
              else
Packit Service 50c9f2
              {
Packit Service 50c9f2
                ti << "0,";
Packit Service 50c9f2
              }
Packit Service 50c9f2
              bool found=FALSE;
Packit Service 50c9f2
              overloadedFunction = ((prevScope!=0 && scope==prevScope) ||
Packit Service 50c9f2
                  (scope && scope==nextScope)
Packit Service 50c9f2
                  ) && md &&
Packit Service 50c9f2
                (md->isFunction() || md->isSlot());
Packit Service 50c9f2
              QCString prefix;
Packit Service 50c9f2
              if (md) prefix=convertToXML(md->localName());
Packit Service 50c9f2
              if (overloadedFunction) // overloaded member function
Packit Service 50c9f2
              {
Packit Service 50c9f2
                prefix+=convertToXML(md->argsString());
Packit Service 50c9f2
                // show argument list to disambiguate overloaded functions
Packit Service 50c9f2
              }
Packit Service 50c9f2
              else if (md) // unique member function
Packit Service 50c9f2
              {
Packit Service 50c9f2
                prefix+="()"; // only to show it is a function
Packit Service 50c9f2
              }
Packit Service 50c9f2
              QCString name;
Packit Service 50c9f2
              if (d->definitionType()==Definition::TypeClass)
Packit Service 50c9f2
              {
Packit Service 50c9f2
                name = convertToXML(((ClassDef*)d)->displayName());
Packit Service 50c9f2
                found = TRUE;
Packit Service 50c9f2
              }
Packit Service 50c9f2
              else if (d->definitionType()==Definition::TypeNamespace)
Packit Service 50c9f2
              {
Packit Service 50c9f2
                name = convertToXML(((NamespaceDef*)d)->displayName());
Packit Service 50c9f2
                found = TRUE;
Packit Service 50c9f2
              }
Packit Service 50c9f2
              else if (scope==0 || scope==Doxygen::globalScope) // in global scope
Packit Service 50c9f2
              {
Packit Service 50c9f2
                if (md)
Packit Service 50c9f2
                {
Packit Service 50c9f2
                  FileDef *fd = md->getBodyDef();
Packit Service 50c9f2
                  if (fd==0) fd = md->getFileDef();
Packit Service 50c9f2
                  if (fd)
Packit Service 50c9f2
                  {
Packit Service 50c9f2
                    if (!prefix.isEmpty()) prefix+=": ";
Packit Service 50c9f2
                    name = prefix + convertToXML(fd->localName());
Packit Service 50c9f2
                    found = TRUE;
Packit Service 50c9f2
                  }
Packit Service 50c9f2
                }
Packit Service 50c9f2
              }
Packit Service 50c9f2
              else if (md && (md->getClassDef() || md->getNamespaceDef()))
Packit Service 50c9f2
                // member in class or namespace scope
Packit Service 50c9f2
              {
Packit Service 50c9f2
                SrcLangExt lang = md->getLanguage();
Packit Service 50c9f2
                name = convertToXML(d->getOuterScope()->qualifiedName())
Packit Service 50c9f2
                  + getLanguageSpecificSeparator(lang) + prefix;
Packit Service 50c9f2
                found = TRUE;
Packit Service 50c9f2
              }
Packit Service 50c9f2
              else if (scope) // some thing else? -> show scope
Packit Service 50c9f2
              {
Packit Service 50c9f2
                name = prefix + convertToXML(scope->name());
Packit Service 50c9f2
                found = TRUE;
Packit Service 50c9f2
              }
Packit Service 50c9f2
              if (!found) // fallback
Packit Service 50c9f2
              {
Packit Service 50c9f2
                name = prefix + "("+theTranslator->trGlobalNamespace()+")";
Packit Service 50c9f2
              }
Packit Service 50c9f2
Packit Service 50c9f2
              ti << "'" << name << "'";
Packit Service 50c9f2
Packit Service 50c9f2
              prevScope = scope;
Packit Service 50c9f2
              childCount++;
Packit Service 50c9f2
            }
Packit Service 50c9f2
Packit Service 50c9f2
            ti << "]]";
Packit Service 50c9f2
          }
Packit Service 50c9f2
          ti << "]";
Packit Service 50c9f2
          itemCount++;
Packit Service 50c9f2
        }
Packit Service 50c9f2
        if (!firstEntry)
Packit Service 50c9f2
        {
Packit Service 50c9f2
          ti << endl;
Packit Service 50c9f2
        }
Packit Service 50c9f2
Packit Service 50c9f2
        ti << "];" << endl;
Packit Service 50c9f2
Packit Service 50c9f2
      }
Packit Service 50c9f2
      else
Packit Service 50c9f2
      {
Packit Service 50c9f2
        err("Failed to open file '%s' for writing...\n",fileName.data());
Packit Service 50c9f2
      }
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
Packit Service 50c9f2
  {
Packit Service 50c9f2
    QFile f(searchDirName+"/searchdata.js");
Packit Service 50c9f2
    if (f.open(IO_WriteOnly))
Packit Service 50c9f2
    {
Packit Service 50c9f2
      FTextStream t(&f);
Packit Service 50c9f2
      t << "var indexSectionsWithContent =" << endl;
Packit Service 50c9f2
      t << "{" << endl;
Packit Service 50c9f2
      bool first=TRUE;
Packit Service 50c9f2
      int j=0;
Packit Service 50c9f2
      for (i=0;i
Packit Service 50c9f2
      {
Packit Service 50c9f2
        if (g_searchIndexInfo[i].symbolList.count()>0)
Packit Service 50c9f2
        {
Packit Service 50c9f2
          if (!first) t << "," << endl;
Packit Service 50c9f2
          t << "  " << j << ": \"";
Packit Service 50c9f2
Packit Service 50c9f2
          SIntDict<SearchIndexList>::Iterator it(g_searchIndexInfo[i].symbolList);
Packit Service 50c9f2
          SearchIndexList *sl;
Packit Service 50c9f2
          for (it.toFirst();(sl=it.current());++it) // for each letter
Packit Service 50c9f2
          {
Packit Service 50c9f2
            t << QString( QChar( sl->letter() ) ).utf8();
Packit Service 50c9f2
          }
Packit Service 50c9f2
          t << "\"";
Packit Service 50c9f2
          first=FALSE;
Packit Service 50c9f2
          j++;
Packit Service 50c9f2
        }
Packit Service 50c9f2
      }
Packit Service 50c9f2
      if (!first) t << "\n";
Packit Service 50c9f2
      t << "};" << endl << endl;
Packit Service 50c9f2
      t << "var indexSectionNames =" << endl;
Packit Service 50c9f2
      t << "{" << endl;
Packit Service 50c9f2
      first=TRUE;
Packit Service 50c9f2
      j=0;
Packit Service 50c9f2
      for (i=0;i
Packit Service 50c9f2
      {
Packit Service 50c9f2
        if (g_searchIndexInfo[i].symbolList.count()>0)
Packit Service 50c9f2
        {
Packit Service 50c9f2
          if (!first) t << "," << endl;
Packit Service 50c9f2
          t << "  " << j << ": \"" << g_searchIndexInfo[i].name << "\"";
Packit Service 50c9f2
          first=FALSE;
Packit Service 50c9f2
          j++;
Packit Service 50c9f2
        }
Packit Service 50c9f2
      }
Packit Service 50c9f2
      if (!first) t << "\n";
Packit Service 50c9f2
      t << "};" << endl << endl;
Packit Service 50c9f2
      t << "var indexSectionLabels =" << endl;
Packit Service 50c9f2
      t << "{" << endl;
Packit Service 50c9f2
      first=TRUE;
Packit Service 50c9f2
      j=0;
Packit Service 50c9f2
      for (i=0;i
Packit Service 50c9f2
      {
Packit Service 50c9f2
        if (g_searchIndexInfo[i].symbolList.count()>0)
Packit Service 50c9f2
        {
Packit Service 50c9f2
          if (!first) t << "," << endl;
Packit Service 50c9f2
          t << "  " << j << ": \"" << convertToXML(g_searchIndexInfo[i].text) << "\"";
Packit Service 50c9f2
          first=FALSE;
Packit Service 50c9f2
          j++;
Packit Service 50c9f2
        }
Packit Service 50c9f2
      }
Packit Service 50c9f2
      if (!first) t << "\n";
Packit Service 50c9f2
      t << "};" << endl << endl;
Packit Service 50c9f2
    }
Packit Service 50c9f2
    ResourceMgr::instance().copyResource("search.js",searchDirName);
Packit Service 50c9f2
  }
Packit Service 50c9f2
  {
Packit Service 50c9f2
    QFile f(searchDirName+"/nomatches.html");
Packit Service 50c9f2
    if (f.open(IO_WriteOnly))
Packit Service 50c9f2
    {
Packit Service 50c9f2
      FTextStream t(&f);
Packit Service 50c9f2
      t << "
Packit Service 50c9f2
           "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl;
Packit Service 50c9f2
      t << "<html><head><title></title>" << endl;
Packit Service 50c9f2
      t << "<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>" << endl;
Packit Service 50c9f2
      t << "<link rel=\"stylesheet\" type=\"text/css\" href=\"search.css\"/>" << endl;
Packit Service 50c9f2
      t << "<script type=\"text/javascript\" src=\"search.js\"></script>" << endl;
Packit Service 50c9f2
      t << "</head>" << endl;
Packit Service 50c9f2
      t << "<body class=\"SRPage\">" << endl;
Packit Service 50c9f2
      t << "
" << endl;
Packit Service 50c9f2
      t << "
"
Packit Service 50c9f2
        << theTranslator->trNoMatches() << "" << endl;
Packit Service 50c9f2
      t << "" << endl;
Packit Service 50c9f2
      t << "</body>" << endl;
Packit Service 50c9f2
      t << "</html>" << endl;
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
  Doxygen::indexList->addStyleSheetFile("search/search.js");
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
const SearchIndexInfo *getSearchIndices()
Packit Service 50c9f2
{
Packit Service 50c9f2
  return g_searchIndexInfo;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
//---------------------------------------------------------------------------------------------
Packit Service 50c9f2
Packit Service 50c9f2
SearchIndexList::SearchIndexList(uint letter)
Packit Service 50c9f2
  : SDict< SearchDefinitionList >(17,FALSE), m_letter(letter)
Packit Service 50c9f2
{
Packit Service 50c9f2
  setAutoDelete(TRUE);
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
SearchIndexList::~SearchIndexList()
Packit Service 50c9f2
{
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
void SearchIndexList::append(Definition *d)
Packit Service 50c9f2
{
Packit Service 50c9f2
  QCString dispName = d->localName();
Packit Service 50c9f2
  SearchDefinitionList *l = find(dispName);
Packit Service 50c9f2
  if (l==0)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    if (d->definitionType()==Definition::TypeGroup)
Packit Service 50c9f2
    {
Packit Service 50c9f2
      dispName = ((GroupDef*)d)->groupTitle();
Packit Service 50c9f2
    }
Packit Service 50c9f2
    else if (d->definitionType()==Definition::TypePage)
Packit Service 50c9f2
    {
Packit Service 50c9f2
      dispName = ((PageDef*)d)->title();
Packit Service 50c9f2
    }
Packit Service 50c9f2
    l=new SearchDefinitionList(searchId(dispName),dispName);
Packit Service 50c9f2
    SDict< SearchDefinitionList >::append(dispName,l);
Packit Service 50c9f2
  }
Packit Service 50c9f2
  l->append(d);
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
uint SearchIndexList::letter() const
Packit Service 50c9f2
{
Packit Service 50c9f2
  return m_letter;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
int SearchIndexList::compareValues(const SearchDefinitionList *md1, const SearchDefinitionList *md2) const
Packit Service 50c9f2
{
Packit Service 50c9f2
  QCString n1 = md1->getFirst()->localName();
Packit Service 50c9f2
  QCString n2 = md2->getFirst()->localName();
Packit Service 50c9f2
  return qstricmp(n1.data(),n2.data());
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
//---------------------------------------------------------------------------------------------
Packit Service 50c9f2
Packit Service 50c9f2
void initSearchIndexer()
Packit Service 50c9f2
{
Packit Service 50c9f2
  static bool searchEngine      = Config_getBool(SEARCHENGINE);
Packit Service 50c9f2
  static bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
Packit Service 50c9f2
  static bool externalSearch    = Config_getBool(EXTERNAL_SEARCH);
Packit Service 50c9f2
  if (searchEngine && serverBasedSearch)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    if (externalSearch) // external tools produce search index and engine
Packit Service 50c9f2
    {
Packit Service 50c9f2
      Doxygen::searchIndex = new SearchIndexExternal;
Packit Service 50c9f2
    }
Packit Service 50c9f2
    else // doxygen produces search index and engine
Packit Service 50c9f2
    {
Packit Service 50c9f2
      Doxygen::searchIndex = new SearchIndex;
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
  else // no search engine or pure javascript based search function
Packit Service 50c9f2
  {
Packit Service 50c9f2
    Doxygen::searchIndex = 0;
Packit Service 50c9f2
  }
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
void finializeSearchIndexer()
Packit Service 50c9f2
{
Packit Service 50c9f2
  delete Doxygen::searchIndex;
Packit Service 50c9f2
}