summaryrefslogtreecommitdiffstats
path: root/src/doxysearch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/doxysearch.cpp')
-rw-r--r--src/doxysearch.cpp1080
1 files changed, 0 insertions, 1080 deletions
diff --git a/src/doxysearch.cpp b/src/doxysearch.cpp
deleted file mode 100644
index ebdf223..0000000
--- a/src/doxysearch.cpp
+++ /dev/null
@@ -1,1080 +0,0 @@
-/******************************************************************************
- *
- *
- *
- * Copyright (C) 1997-2003 by Dimitri van Heesch.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation under the terms of the GNU General Public License is hereby
- * granted. No representations are made about the suitability of this software
- * for any purpose. It is provided "as is" without express or implied warranty.
- * See the GNU General Public License for more details.
- *
- * Documents produced by Doxygen are derivative works derived from the
- * input used in their production; they are not affected by this license.
- *
- */
-
-// includes
-
-#ifdef _WIN32
-#include <windows.h> // for AllocConsole
-#endif
-
-
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <sys/stat.h>
-#ifdef PROFILING
-#include <sys/time.h>
-#include <unistd.h>
-#endif
-
-// defines
-
-#ifndef bool
-#define bool int
-#endif
-
-#define MAXSTRLEN 1024
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#define NORMAL 1 // OR search results
-#define INCLUDE 2 // AND search results
-#define EXCLUDE 3 // AND NOT search results
-
-#define TERMMASK (1<<31)
-#define OFFSETMASK (~TERMMASK)
-
-// structs
-
-//----------------------------------------------------------------------------
-
-struct FileInfo
-{
- FileInfo() { name[0]='\0'; f=0; url=0; }
- ~FileInfo() { if (f) fclose(f);
- delete[] url;
- }
- FILE *f;
- char name[MAXSTRLEN];
- int index;
- int refOffset;
- char *url;
- FileInfo *next;
-};
-
-//----------------------------------------------------------------------------
-
-struct FileList
-{
- FileList() { first=0; last=0; index=0; }
- ~FileList() { FileInfo *fi=first;
- while (fi) { FileInfo *ofi=fi; fi=fi->next; delete ofi; }
- }
- FileInfo *add()
- {
- FileInfo *nf=new FileInfo;
- nf->next=0;
- nf->index=index++;
- if (last) { last->next=nf; last=nf; } else { first=nf; last=nf; }
- return nf;
- }
- FileInfo *first;
- FileInfo *last;
- int index;
-};
-
-//----------------------------------------------------------------------------
-
-struct WordInfo
-{
- WordInfo() { word=0; }
- ~WordInfo() { delete[] word; }
- char *word;
- int freq;
- WordInfo *next;
-};
-
-//----------------------------------------------------------------------------
-
-struct WordList
-{
- WordList() { first=0; last=0; }
- ~WordList() { WordInfo *wi=first;
- while (wi) { WordInfo *owi=wi; wi=wi->next; delete owi; }
- }
- void add(const char *word,int freq)
- {
- WordInfo *nw=new WordInfo;
- nw->word = new char[strlen(word)+1];
- strcpy(nw->word,word);
- nw->freq=freq;
- nw->next=0;
- if (last) { last->next=nw; last=nw; } else { first=nw; last=nw; }
- }
- WordInfo *first;
- WordInfo *last;
-};
-
-//----------------------------------------------------------------------------
-
-struct SearchDoc
-{
- FileInfo *fileInfo;
- int index;
- int freq;
- double rank;
- SearchDoc *next;
-};
-
-//----------------------------------------------------------------------------
-
-struct SearchResults
-{
- SearchResults() { totalFreq=0; docList=0; last=0; }
- ~SearchResults() { SearchDoc *d=docList;
- while (d) { SearchDoc *od=d; d=d->next; delete od; }
- }
- void add(FileInfo *fi,int index,int freq)
- {
- SearchDoc *nd=new SearchDoc;
- nd->fileInfo=fi;
- nd->index=index;
- nd->freq=freq;
- nd->next=0;
- if (last) { last->next=nd; last=nd; } else { docList=nd; last=nd; }
- }
- SearchDoc *docList;
- SearchDoc *last;
- int totalFreq;
-};
-
-//----------------------------------------------------------------------------
-
-// global vars
-
-static WordList wordList;
-static FileList fileList;
-static char cgiBin[MAXSTRLEN];
-static char queryInput[MAXSTRLEN];
-static char encQueryInput[MAXSTRLEN];
-static char firstDocUrl[MAXSTRLEN];
-static bool nameOnly;
-static bool wordOnly;
-static bool helpOnly;
-static int page;
-static char *headerBuf=0;
-static char *footerBuf=0;
-
-//----------------------------------------------------------------------------
-
-// functions
-
-void printHeader()
-{
- if (headerBuf)
- {
- printf("Content-Type: text/html\r\n\r\n%s",headerBuf);
- }
- else
- {
- printf("Content-Type: text/html\r\n\r\n");
- printf("<html><head><title>Search the documentation</title></head>\n"
- "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#0000ee\" \n"
- "vlink=\"#551a8b\" alink=\"#ff0000\">\n");
- }
-}
-
-//----------------------------------------------------------------------------
-
-void printFooter()
-{
- if (footerBuf)
- {
- printf("%s",footerBuf);
- }
- else
- {
- printf("</body></html>\n");
- }
-}
-
-//----------------------------------------------------------------------------
-
-void message(const char *fmt,...)
-{
- printHeader();
- printf("<h2>");
- va_list args;
- va_start(args, fmt);
- vfprintf(stdout, fmt, args);
- va_end(args);
- printf("</h2>");
- printFooter();
-}
-
-//----------------------------------------------------------------------------
-
-void printSearchPage(bool open=FALSE)
-{
- printf("<form name=doxyform method=GET action=\"%s\">\n"
- "<center>\n"
- "<input type=hidden name=page value=0>\n"
- "<table border=0 bgcolor=\"#ffffcc\" cellspacing=0 cellpadding=4>\n"
- " <tr>\n"
- " <td valign=top><font size=-1 face=\"arial, helvetica\"><b>"
- " Search for\n"
- " <select name=which>\n"
- " <option value=string %s>strings\n"
- " <option value=word %s>words\n"
- " </select>\n"
- " in function and class\n"
- " <select name=what>\n"
- " <option value=doc %s>documentation\n"
- " <option value=name %s>names</select></b></font>\n"
- " </td>\n"
- " <td valign=top align=right>\n"
- " <a href=\"%s?help=on\"><font size=-1>Help</font></a>\n"
- " </td>\n"
- " </tr>\n"
- " <tr>\n"
- " <td><input name=query size=44 wrap=virtual maxlength=1000 value=\"%s\">\n"
- " </td>\n"
- " <td><input type=image src=\"%s/search.png\" height=26 width=120 border=0 name=\"search\">\n"
- " </td>\n"
- " </tr>\n",
- cgiBin,
- (wordOnly?"":"selected"),(wordOnly?"selected":""),
- (nameOnly?"":"selected"),(nameOnly?"selected":""),
- cgiBin,queryInput,firstDocUrl);
- if (!open)
- {
- printf("</table>\n</center></form>\n");
- }
-}
-
-//----------------------------------------------------------------------------
-
-int readInt(FILE *f)
-{
- unsigned char c_24 = fgetc(f);
- unsigned char c_16 = fgetc(f);
- unsigned char c_08 = fgetc(f);
- unsigned char c_00 = fgetc(f);
- return ((unsigned int)c_24<<24)+
- ((unsigned int)c_16<<16)+
- ((unsigned int)c_08<<8)+
- c_00;
- //return (fgetc(f)<<24)+(fgetc(f)<<16)+(fgetc(f)<<8)+fgetc(f);
-}
-
-//----------------------------------------------------------------------------
-
-int readEncodedNumber(FILE *f)
-{
- int n=0,b,s=0;
- do { b=fgetc(f); n|=(b&0x7f)<<s; s+=7; } while (b&0x80);
- return n;
-}
-
-void readString(FILE *f,char *s,int n)
-{
- int i=0,b;
- if (n<=0) return;
- while (i<n-1 && (b=fgetc(f))!=0) s[i++]=b;
- s[i]='\0';
-}
-
-//----------------------------------------------------------------------------
-
-bool searchRecursive(SearchResults *sr,FileInfo *fi,const char *word)
-{
- char entry[MAXSTRLEN];
- readString(fi->f,entry,MAXSTRLEN);
- while (entry[0]!='\0')
- {
- //printf("Found entry `%s'\n",entry);
- int i=0, w=word[0], e=entry[0];
- while (w!=0 && e!=0 && w==e) { i++; w=word[i]; e=entry[i]; }
- if (w==0 && e!=0) // word is a substring of entry
- {
- if (wordOnly) return FALSE; // no full word match
- //printf("Word found as substring of `%s%s'\n",&word[-index],&entry[i]);
- int offset=readInt(fi->f); // <= follow for extensions
- if (!(offset&TERMMASK)) // extra info available
- {
- int tfreq=readEncodedNumber(fi->f);
- sr->totalFreq+=tfreq;
- //printf("Total frequency %d\n",tfreq);
- int s=-1,k;
- while ((k=readEncodedNumber(fi->f))!=0)
- {
- bool inName = (k&2)==2;
- s+=(k>>3);
- int freq=readEncodedNumber(fi->f);
- //printf("Doc index %d frequency %d\n",s,freq);
- if (!nameOnly || inName)
- //addResult(fi,sr,s,freq);
- sr->add(fi,s,freq);
- }
- }
- return TRUE;
- }
- else if (e==0) // entry is a substring of word
- {
- if (w==0) // word is equal to entry => exact match found
- {
- int offset=readInt(fi->f); // <= follow for extensions
- if (!(offset&TERMMASK)) // extra info available
- {
- //printf("Match found\n");
- int tfreq=readEncodedNumber(fi->f);
- sr->totalFreq+=tfreq;
- //printf("Total frequency %d\n",tfreq);
- int s=-1,k;
- while ((k=readEncodedNumber(fi->f))!=0)
- {
- bool fullWord = (k&1)==1;
- bool inName = (k&2)==2;
- bool wordInName = (k&4)==4;
- s+=(k>>3);
- int freq=readEncodedNumber(fi->f);
- if (nameOnly && wordOnly)
- {
- if (wordInName) sr->add(fi,s,freq);
- }
- else if (!nameOnly && wordOnly)
- {
- if (fullWord) sr->add(fi,s,freq);
- }
- else if (nameOnly && !wordOnly)
- {
- if (inName) sr->add(fi,s,freq);
- }
- else // !nameOnly && !wordOnly
- {
- sr->add(fi,s,freq);
- }
- }
- }
- return TRUE;
- }
- else // follow branch to next entry
- {
- int offset=readInt(fi->f);
- if ((offset&OFFSETMASK)==0) // no next entry (leaf node)
- {
- return FALSE;
- }
- else // follow branch
- {
- fseek(fi->f,offset&OFFSETMASK,SEEK_SET);
- //printf("Recursive call; jump to %lx\n",ftell(f));
- return searchRecursive(sr,fi,&word[i]);
- }
- }
- }
- else // skip rest of the entry
- {
- int offset=readInt(fi->f);
- if (!(offset&TERMMASK)) while (readEncodedNumber(fi->f)!=0);
- }
- readString(fi->f,entry,MAXSTRLEN);
- }
- //printf("Sorry no match found\n");
- return FALSE;
-}
-
-//----------------------------------------------------------------------------
-
-
-void searchIndex(const char *word,SearchResults *results)
-{
- FileInfo *fi=fileList.first;
- while (fi)
- {
- fi->f = fopen(fi->name, "rb");
- fseek(fi->f,8,SEEK_SET);
- searchRecursive(results,fi,word);
- fclose(fi->f);
- fi->f=0;
- fi=fi->next;
- }
-
- SearchDoc *ds = results->docList;
- while (ds)
- {
- ds->rank = ds->freq/(double)results->totalFreq;
- ds = ds->next;
- }
-
- wordList.add(word,results->totalFreq);
-}
-
-//----------------------------------------------------------------------------
-
-extern "C" int sortResults(const void *a1,const void *a2)
-{
- SearchDoc **d1=(SearchDoc **)a1;
- SearchDoc **d2=(SearchDoc **)a2;
- if ((*d1)->rank > (*d2)->rank)
- return -1;
- else if ((*d1)->rank == (*d2)->rank)
- return 0;
- else
- return 1;
-}
-
-//----------------------------------------------------------------------------
-
-void generateResults(SearchResults *sr)
-{
- // compute the maximum rank
- SearchDoc *ds = sr->docList;
- double maxRank = 0.00000001;
- int resultCount=0;
- if (ds)
- {
- while (ds)
- {
- if (ds->rank>maxRank) maxRank = ds->rank;
- ds = ds->next;
- }
-
- // scale ranks, so the highest is 1 and count the number of links
- double oneOverMaxRank = 1.0/maxRank;
- ds = sr->docList;
- while (ds)
- {
- ds->rank *= oneOverMaxRank;
- resultCount++;
- ds = ds->next;
- }
- }
- SearchDoc **docPtrArray=0;
- if (resultCount>0)
- {
- docPtrArray=(SearchDoc **)calloc(resultCount,sizeof(SearchDoc *));
- int offset=0;
- ds = sr->docList;
- while (ds)
- {
- docPtrArray[offset++]=ds;
- ds = ds->next;
- }
- qsort(docPtrArray,resultCount,sizeof(SearchDoc *),sortResults);
- }
-
- // start generating output
- printHeader();
- printSearchPage(TRUE);
-
- printf(" <tr bgcolor=#ffffff>\n"
- " <td colspan=2>"
- "<br><h3>Search results</h3>\n"
- " </td>\n"
- " </tr>\n");
- if (resultCount==0) // nothing found
- {
- printf(" <tr bgcolor=#ffffff>\n"
- " <td colspan=2>Sorry, no documents matching your query.\n"
- " </td>\n"
- " </tr>\n");
- }
- else // something found
- {
- printf(" <tr bgcolor=#ffffff>\n"
- " <td colspan=2>"
- "Found <b>%d</b> document%s matching your query. ",
- resultCount,resultCount==1?"":"s");
-
- if (resultCount>1)
- printf("Showing best matches first.\n");
-
- printf(" <br><br>\n");
- printf(" </td>\n"
- " </tr>\n");
-
- const int lpp=20;
- int numPages = (resultCount+lpp-1)/lpp;
-
- // clip page
- if (page<0) page=0;
- if (page>=numPages) page=numPages-1;
- int skipEntries = page * lpp;
- int pageEntries = lpp;
-
- printf(" <tr><td colspan=2 bgcolor=\"#4040c0\">"
- "<center><b><font color=\"#ffffff\">Page %d / %d</font></b>"
- "</center></td></tr>\n",page+1,numPages);
- printf(" <tr bgcolor=#ffffff>\n"
- " <td colspan=2>\n"
- " <table border=\"0\" cellspacing=\"2\" cellpadding=\"2\">\n");
- int i;
- for (i=0 ; i < resultCount && pageEntries > 0; i++)
- {
- if (skipEntries == 0)
- {
- SearchDoc *d=docPtrArray[i];
- if (d->fileInfo->f == 0)
- {
- d->fileInfo->f = fopen(d->fileInfo->name, "rb");
- }
- FILE *f=d->fileInfo->f;
- fseek(f,d->fileInfo->refOffset+d->index*4,SEEK_SET);
- int offset=readInt(f);
- fseek(f,offset,SEEK_SET);
- char linkName[MAXSTRLEN];
- char htmlName[MAXSTRLEN];
- readString(f,linkName,MAXSTRLEN);
- readString(f,htmlName,MAXSTRLEN);
- int rank=(int)(d->rank*100+0.5);
- if (rank==0) rank++;
- printf(" <tr><td align=\"right\"><b><font color=#%2x00%2x>%d</font></b>"
- "</td><td><a href=\"%s/%s\">%s</a></td></tr>\n",
- rank*2+55, 255-rank*2, rank,
- d->fileInfo->url, htmlName, linkName);
- pageEntries--;
- if (d->fileInfo->f != 0)
- {
- fclose(d->fileInfo->f);
- d->fileInfo->f = 0;
- }
- }
- else
- {
- skipEntries--;
- }
- }
- printf(" </table>\n"
- " </td>\n"
- " </tr>\n"
- " <tr><td colspan=2 bgcolor=\"#4040c0\"><center>&nbsp;");
-
- if (page>0)
- {
- printf("<a href=\"%s?page=%d&which=%s&what=%s&query=%s\">"
- "<font color=\"ffffff\">prev</font></a>&nbsp;",
- cgiBin, page-1,
- wordOnly?"word":"doc",
- nameOnly?"name":"string",
- encQueryInput);
- }
- int startPage = page-5 < 0 ? 0 : page-5;
- int endPage = page+6 > numPages ? numPages : page+5;
- if (endPage-startPage>1)
- {
- for (i=startPage;i<endPage;i++)
- {
- if (i!=page)
- {
- printf("<a href=\"%s?page=%d&which=%s&what=%s&query=%s\">"
- "<font color=\"ffffff\">%d</font></a>&nbsp;",
- cgiBin, i,
- wordOnly?"word":"doc",
- nameOnly?"name":"string",
- encQueryInput, i+1);
- }
- else
- {
- printf("<b><font color=\"ffffff\">%d</font></b></a>&nbsp;",i+1);
- }
- }
- }
- if (page<numPages-1)
- {
- printf("<a href=\"%s?page=%d&which=%s&what=%s&query=%s\">"
- "<font color=\"ffffff\">next</font></a>",
- cgiBin, page+1,
- wordOnly?"word":"doc",
- nameOnly?"name":"string",
- encQueryInput);
- }
- printf(" &nbsp;</center></td></tr>\n"
- " <tr bgcolor=#ffffff>\n"
- " <td colspan=2><p>\n"
- " Occurrence count: ");
- WordInfo *wi=wordList.first;
- while (wi)
- {
- printf("<b><font color=#ff0000>%s</font></b> ",wi->word);
- if (wi->freq>0) printf("(%d)",wi->freq); else printf("(ignored)");
- wi=wi->next;
- if (wi)
- {
- if (wi->next) printf(", "); else printf(" and ");
- }
- }
- printf("\n"
- " </td>\n"
- " </tr>\n");
- }
- printf("</table>\n</center>\n</form>\n");
- printFooter();
- free(docPtrArray);
-}
-
-//----------------------------------------------------------------------------
-
-void generateHelpPage()
-{
- printHeader();
- printf("<h3>Doxysearch help page</h3>\n"
- "<b>Basic search instructions</b>\n"
- "<ul>\n"
- "Just type in one or more words or fragments of words and press the "
- "search button. Doxysearch will return a list of functions and class names, "
- "whose documentation or name matches one or more of the words. "
- "Documents containing more matches will appear earlier in the list. "
- "\n"
- "</ul>\n"
- "<b>Search modes</b>\n"
- "<ul>\n"
- "Doxysearch has four search modes. From least restrictive to most "
- "restrictive they are:\n"
- " <ul><p>\n"
- " <li><em>Search for strings in the documentation:</em>\n"
- " The words you type will be searched in the documentation as substrings."
- " Typing the word &quot;<b>the</b>&quot; for example, will find "
- " documents containing the words &quot;<b>the</b>&quot;, "
- " &quot;<b>the</b>re&quot;, and &quot;fea<b>the</b>r&quot;.<p>\n"
- " <li><em>Search for words in the documentation:</em>\n"
- " The words you type will be searched in the documentation as words."
- " Typing the word &quot;<b>the</b>&quot; for example, will look "
- " for documents containing the word &quot;<b>the</b>&quot; and not for"
- " documents containing the word &quot;<b>the</b>re&quot;.<p>\n"
- " <li><em>Search for strings in the function and class names:</em>\n"
- " The words you type will be searched in the function and class names "
- " as substrings. Typing the word &quot;<b>set</b>&quot; for example, will "
- " result in a list of links to the documentation of all functions and classes "
- " that contain the word &quot;<b>set</b>&quot; in the name, such as the function "
- " <code><b>set</b>Cursor</code>.<p>\n"
- " <li><em>Search for words in the function and class names:</em>\n"
- " The words you type will be matched against the function and class names."
- " The result will be a list of links to the documentation of all function "
- " and class names that are equal to one of the words.\n"
- " </ul>\n"
- "</ul>\n"
- "<b>Requiring/Excluding words</b>\n"
- "<ul>\n"
- " Often you will know a word that will be guaranteed to appear in a document "
- " for which you are searching. If this is the case, require that the word appears "
- " in all of the results by attaching a &quot;<b>+</b>&quot; to the beginning of "
- " the word. You can quickly reject results by adding a word that appears only "
- " in unwanted documents with a &quot;<b>-</b>&quot; before it."
- "</ul>\n"
- );
-
- printFooter();
-}
-
-//----------------------------------------------------------------------------
-
-void mergeSearchResults(SearchResults *totalResults,
- SearchResults *sr,int mode)
-{
- SearchDoc *otd = 0,
- *td = totalResults->docList,
- *d = sr->docList;
- totalResults->totalFreq += sr->totalFreq;
- if (!d) return; // nothing to add
- while (td && d)
- {
- int otdih = otd ? otd->fileInfo->index : -1,
- otdil = otd ? otd->index : -1,
- tdih = td->fileInfo->index,
- tdil = td->index,
- dih = d->fileInfo->index,
- dil = d->index;
- if (tdih==dih && tdil==dil) // combine results
- {
- if (mode != EXCLUDE)
- {
- td->rank += d->rank;
- td->rank *= 2; // put extra emphasis on multiple word matches
- td->freq += d->freq;
- d = d->next;
- otd = td; td = td->next;
- }
- else // mode == EXCLUDE => remove entry from results
- {
- SearchDoc *tmp=td;
- td=td->next;
- if (otd) otd->next=td; else totalResults->docList = td;
- delete tmp;
- }
- }
- else if ((otdih<dih || (otdih==dih && otdil<dil)) &&
- (tdih>dih || (tdih==dih && tdil>dil))) // insert
- {
- if (mode == NORMAL)
- {
- SearchDoc *nd = new SearchDoc(*d);
- if (otd) otd->next = nd; else totalResults->docList = nd;
- nd->next = td;
- td = nd;
- }
- d = d->next;
- }
- else if (tdih<dih || (tdih==dih && tdil<dil)) // remove or skip
- {
- if (mode == INCLUDE)
- {
- SearchDoc *tmp=td;
- td=td->next;
- if (otd) otd->next=td; else totalResults->docList = td;
- delete tmp;
- }
- else // mode == EXCLUDE or mode == NORMAL
- {
- otd = td; td = td->next;
- }
- }
- }
- if (td==0 && d && mode==NORMAL) // append rest of sr to totalResults
- {
- while (d)
- {
- SearchDoc *nd = new SearchDoc(*d);
- if (otd) otd->next = nd; else totalResults->docList = nd;
- nd->next = 0;
- d = d->next;
- otd = nd;
- }
- }
- if (td && d==0 && mode==INCLUDE) // delete the rest of the results
- {
- while (td)
- {
- SearchDoc *tmp=td;
- td=td->next;
- if (otd) otd->next = td; else totalResults->docList = td;
- delete tmp;
- }
- }
-}
-
-//----------------------------------------------------------------------------
-
-int asciiToHex(char c)
-{
- char l=tolower(c);
- if (l>='0' && l<='9')
- return l-'0';
- else if (l>='a' && l<='f')
- return l+10-'a';
- else // invalid hex char
- return 0;
-}
-
-//----------------------------------------------------------------------------
-
-void fileToBuf(const char *name, char **buf)
-{
- FILE *f;
- struct stat file_stats;
- if ((f=fopen(name,"rb"))==NULL) return;
- if (stat(name,&file_stats)==-1)
- {
- message("Error: could not fstat file %s\n",name);
- exit(1);
- }
- unsigned int len=file_stats.st_size;
- if ((*buf=(char *)malloc(len+1))==NULL)
- {
- message("Error: out of memory\n");
- exit(1);
- }
- if (fread(*buf,1,len,f)!=len)
- {
- message("Error: could not read file %s\n",name);
- exit(1);
- }
- (*buf)[len]='\0';
- fclose(f);
-}
-
-//----------------------------------------------------------------------------
-
-void getConfig(const char *s)
-{
- int l;
- char configFile[MAXSTRLEN];
- strcpy(configFile,s);
-#if defined(_WIN32)
- strcat(configFile,"\\search.cfg");
-#else
- strcat(configFile,"/search.cfg");
-#endif
-
- FILE *f;
- if ((f=fopen(configFile,"r"))==NULL)
- {
- message("Error: could not open config file %s\n",configFile);
- exit(1);
- }
-
- // get the URL to the documentation
- fgets(firstDocUrl,MAXSTRLEN,f);
- l=strlen(firstDocUrl)-1;
- if (firstDocUrl[l]=='\n') firstDocUrl[l]='\0';
- l=strlen(firstDocUrl);
- if (firstDocUrl[l]=='/') firstDocUrl[l]='\0';
-
- // get the URL to the cgi script
- fgets(cgiBin,MAXSTRLEN,f);
- l=strlen(cgiBin)-1;
- if (cgiBin[l]=='\n') cgiBin[l]='\0';
-
- fclose(f);
-
- char headerFile[MAXSTRLEN];
- strcpy(headerFile,s);
-#if defined(_WIN32)
- strcat(headerFile,"\\header.html");
-#else
- strcat(headerFile,"/header.html");
-#endif
- fileToBuf(headerFile,&headerBuf);
-
- char footerFile[MAXSTRLEN];
- strcpy(footerFile,s);
-#if defined(_WIN32)
- strcat(footerFile,"\\footer.html");
-#else
- strcat(footerFile,"/footer.html");
-#endif
- fileToBuf(footerFile,&footerBuf);
-
-}
-
-//----------------------------------------------------------------------------
-// copy and convert string to lower case
-
-void strlowercpy(char *d,const char *s)
-{
- while (*s!='\0') *d++=tolower(*s++); *d='\0';
-}
-
-//----------------------------------------------------------------------------
-
-int main(int argc,char **argv)
-{
-#ifdef _WIN32
- AllocConsole();
-#endif
-
-#ifdef PROFILING
- struct timeval tv_start,tv_end;
- gettimeofday(&tv_start,0);
-#endif
- char *argString=getenv("QUERY_STRING");
- if (argc==1)
- {
- message("Error: invalid number of arguments. "
- "Usage: %s doc_path [doc_path ...]",argv[0]);
- exit(1);
- }
- // read the configuration file for this instance of the search engine
- getConfig(argv[1]);
-
- if (!argString)
- {
- printHeader();
- printSearchPage();
- printFooter();
- exit(1);
- }
-
- SearchResults tsr;
-
- // parse cgi arguments
- char *arg=strtok(argString,"&");
- char *query = 0;
- char *what = 0;
- char *which = 0;
- char *help = 0;
- page = 0;
- while (arg)
- {
- int namelen=strcspn(arg,"=");
- if (!strncmp(arg,"query", namelen)) query = &arg[namelen+1];
- else if (!strncmp(arg,"what", namelen)) what = &arg[namelen+1];
- else if (!strncmp(arg,"which", namelen)) which = &arg[namelen+1];
- else if (!strncmp(arg,"help", namelen)) help = &arg[namelen+1];
- else if (!strncmp(arg,"page", namelen)) page = atoi(&arg[namelen+1]);
- arg=strtok(0,"&");
- }
-
- wordOnly=which ? strcmp(which,"word")==0 : FALSE;
- nameOnly=what ? strcmp(what, "name")==0 : FALSE;
- helpOnly=help ? strcmp(help, "on" )==0 : FALSE;
-
- // store encoded query string
- if (query) strcpy(encQueryInput,query); else encQueryInput[0]='\0';
-
- // convert query string to original input
- char *s=query,*d=queryInput;
- if (s)
- {
- while (*s!='\0')
- {
- char c=*s++;
- if (c=='+')
- *d++=' ';
- else if (c=='%')
- {
- *d=asciiToHex(*s++)*16;
- *d+=asciiToHex(*s++);
- d++;
- }
- else
- *d++=c;
- }
- }
- *d='\0';
-
- if (helpOnly)
- {
- generateHelpPage();
- exit(1);
- }
-
- // read search index files
- int argIndex=0;
- for (argIndex=1;argIndex<argc;argIndex++)
- {
- char configFile[MAXSTRLEN];
- strcpy(configFile,argv[argIndex]);
-#if defined(_WIN32)
- strcat(configFile,"\\search.cfg");
-#else
- strcat(configFile,"/search.cfg");
-#endif
-
- char indexFile[MAXSTRLEN];
- strcpy(indexFile,argv[argIndex]);
-#if defined(_WIN32)
- strcat(indexFile,"\\search.idx");
-#else
- strcat(indexFile,"/search.idx");
-#endif
-
- FileInfo *fi=fileList.add();
- FILE *g;
-
- strcpy(fi->name,indexFile);
- if ((fi->f=fopen(indexFile,"rb"))==NULL)
- {
- message("Error: could not open index file %s\n",indexFile);
- exit(1);
- }
- if ((g=fopen(configFile,"r"))==NULL)
- {
- message("Error: could not open config file %s\n",configFile);
- exit(1);
- }
-
- // get URL to the documentation
- char tmp[MAXSTRLEN];
- fgets(tmp,MAXSTRLEN,g);
- if (tmp[strlen(tmp)-1]=='\n') tmp[strlen(tmp)-1]='\0';
- if (tmp[strlen(tmp)-1]=='/') tmp[strlen(tmp)-1]='\0';
- fi->url = new char[strlen(tmp)+1];
- strcpy(fi->url,tmp);
- fclose(g);
-
- // read & check the format of the search index file
- fseek(fi->f,0,SEEK_SET);
- char header[5];
- if (fread(header,1,4,fi->f)!=4)
- {
- message("Error: Couldn't read header of the index file %s\n",indexFile);
- exit(1);
- }
- header[4]='\0';
- if (strcmp(header,"DOXI"))
- {
- message("Error: Index file %s has an unknown format\n",indexFile);
- exit(1);
- }
- // read and store the offset to the link index
- fi->refOffset=readInt(fi->f);
- fclose(fi->f);
- fi->f = 0;
- }
-
- char *word;
- char wordString[MAXSTRLEN];
-
- // search for included words
- strlowercpy(wordString,queryInput);
- word=strtok(wordString," ");
- bool first=TRUE;
- while (word)
- {
- if (word[0]=='+') // + character => include
- {
- SearchResults sr;
- searchIndex(&word[1],&sr);
- if (first)
- mergeSearchResults(&tsr,&sr,NORMAL);
- else
- mergeSearchResults(&tsr,&sr,INCLUDE);
- first=FALSE;
- }
- word=strtok(0," ");
- }
-
- // search for normal words
- strlowercpy(wordString,queryInput);
- word=strtok(wordString," ");
- while (word)
- {
- if (word[0]!='-' && word[0]!='+') // normal word
- {
- SearchResults sr;
- searchIndex(word,&sr);
- mergeSearchResults(&tsr,&sr,NORMAL);
- }
- word=strtok(0," ");
- }
-
- // search for excluded words
- strlowercpy(wordString,queryInput);
- word=strtok(wordString," ");
- while (word)
- {
- if (word[0]=='-') // - character => exclude
- {
- SearchResults sr;
- searchIndex(&word[1],&sr);
- mergeSearchResults(&tsr,&sr,EXCLUDE);
- }
- word=strtok(0," ");
- }
-
- // write results to HTML page
- generateResults(&tsr);
-
- free(headerBuf);
- free(footerBuf);
-
-#ifdef PROFILING
- gettimeofday(&tv_end,0);
- printf("processing time %3.3f msec\n",
- ((tv_end.tv_sec-tv_start.tv_sec)*1000000+
- tv_end.tv_usec-tv_start.tv_usec)/1000.0
- );
-#endif
- return 0;
-}