diff options
Diffstat (limited to 'src/doxysearch.cpp')
-rw-r--r-- | src/doxysearch.cpp | 1080 |
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> "); - - if (page>0) - { - printf("<a href=\"%s?page=%d&which=%s&what=%s&query=%s\">" - "<font color=\"ffffff\">prev</font></a> ", - 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> ", - cgiBin, i, - wordOnly?"word":"doc", - nameOnly?"name":"string", - encQueryInput, i+1); - } - else - { - printf("<b><font color=\"ffffff\">%d</font></b></a> ",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(" </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 "<b>the</b>" for example, will find " - " documents containing the words "<b>the</b>", " - " "<b>the</b>re", and "fea<b>the</b>r".<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 "<b>the</b>" for example, will look " - " for documents containing the word "<b>the</b>" and not for" - " documents containing the word "<b>the</b>re".<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 "<b>set</b>" for example, will " - " result in a list of links to the documentation of all functions and classes " - " that contain the word "<b>set</b>" 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 "<b>+</b>" to the beginning of " - " the word. You can quickly reject results by adding a word that appears only " - " in unwanted documents with a "<b>-</b>" 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; -} |