diff --git a/Examples/Mainpage.dox b/Examples/Mainpage.dox index 002b0e1e4386f66c559fe9160d7c110c6fa96bae..f8ef7ebe0942c8be8b6608d4f7f79d2f13ce6444 100644 --- a/Examples/Mainpage.dox +++ b/Examples/Mainpage.dox @@ -62,6 +62,8 @@ specific type of socket which returns ethernet packets directly from the network wire. By uncommenting the last line, you may switch the interface into promiscuous mode. + \until // + We will now read packets from the socket forever, that is until the user hits Ctrl-C \skip while @@ -158,9 +160,9 @@ \see \ref components \n \ref build \n - <a href="../../Socket/doc/html/index.html"><b>libSocket API reference</b></a> \n - <a href="../../Packets/doc/html/index.html"><b>libPackets API reference</b></a> \n - <a href="../../Utils/doc/html/index.html"><b>libUtils API reference</b></a> + <a href="../../../Socket/doc/html/index.html"><b>libSocket API reference</b></a> \n + <a href="../../../Packets/doc/html/index.html"><b>libPackets API reference</b></a> \n + <a href="../../../Utils/doc/html/index.html"><b>libUtils API reference</b></a> */ diff --git a/doclib/Doxyfile.global b/doclib/Doxyfile.global index b959702c357459cfa901adbd78969dcd4bd98966..5d8dbba6240fac5408b101fe1aa9b3c0f314a509 100644 --- a/doclib/Doxyfile.global +++ b/doclib/Doxyfile.global @@ -21,6 +21,7 @@ INTERNAL_DOCS = YES SOURCE_BROWSER = YES ALPHABETICAL_INDEX = YES COLS_IN_ALPHA_INDEX = 3 +SEARCHENGINE = YES MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = YES diff --git a/doclib/doxy-header-overview.html b/doclib/doxy-header-overview.html index 9a4bf37557b8e8d56d28bb2d8609b09280c55ebf..050cc2bd526fc9f4949088c2bfabeefb49a4cbf6 100644 --- a/doclib/doxy-header-overview.html +++ b/doclib/doxy-header-overview.html @@ -13,6 +13,11 @@ div.tabs ul li.$projectname a { background-color: #EDE497; } <div id="head"> <h1>SENF Extensible Network Framework</h1> <h2>Introduction and Overview</h2> + <div id="search"> + <form action="../../doclib/search.php" method="get"> + Search: <input type="text" name="query" size="20" accesskey="s"/> + </form> + </div> </div> <div id="content1"> diff --git a/doclib/doxy-header.html b/doclib/doxy-header.html index b3499de5f4d151382d0773b0a4afa65ba88c3ca7..ba83bb6b3b0c58fa3807e6333587344c845045c1 100644 --- a/doclib/doxy-header.html +++ b/doclib/doxy-header.html @@ -13,6 +13,11 @@ div.tabs ul li.$projectname a { background-color: #EDE497; } <div id="head"> <h1>SENF Extensible Network Framework</h1> <h2>Documentation and API reference</h2> + <div id="search"> + <form action="../../../doclib/search.php" method="get"> + Search: <input type="text" name="query" size="20" accesskey="s"/> + </form> + </div> </div> <div id="content1"> diff --git a/doclib/html-munge.xsl b/doclib/html-munge.xsl index 341275bf315a96b8e8ed1a8ae9b505aa14560612..a7f17c3f8083bc580c6a297fc479a60f7711d65a 100644 --- a/doclib/html-munge.xsl +++ b/doclib/html-munge.xsl @@ -10,6 +10,9 @@ </xsl:copy> </xsl:template> + <xsl:template match="li[form]"> + </xsl:template> + <!-- Add 'class' attribute to some special paragraphs/lists --> <xsl:template name="add-class"> @@ -74,5 +77,5 @@ <xsl:with-param name="class">anchor</xsl:with-param> </xsl:call-template> </xsl:template> - + </xsl:stylesheet> diff --git a/doclib/search.php b/doclib/search.php new file mode 100644 index 0000000000000000000000000000000000000000..7fc04f5a2c32202ffbfc1871a235c60ec457215d --- /dev/null +++ b/doclib/search.php @@ -0,0 +1,64 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<title>Search</title> +<link href="../doc/html/doxygen.css" rel="stylesheet" type="text/css"> +<link href="senf.css" rel="stylesheet" type="text/css"> +<?php include 'search_functions.php'; ?> +</head> +<body> + +<div id="head"> + <h1>SENF Extensible Network Framework</h1> + <h2>Search Results</h2> + <div id="search"> + <form action="search.php" method="get"> + Search: <?php inputfield(); ?> + </form> + </div> +</div> + +<div id="content1"> + <div id="content2"> + <div class="tabs menu"> + <ul> + <li class="Overview"><a href="../doc/html/index.html">Overview</a></li> + <li class="libSocket"><a href="../Socket/doc/html/index.html">libSocket</a></li> + <li class="libPackets"><a href="../Packets/doc/html/index.html">libPackets</a></li> + <li class="libScheduler"><a href="../Scheduler/doc/html/index.html">libScheduler</a></li> + <li class="libUtils"><a href="../Utils/doc/html/index.html">libUtils</a></li> + <li class="Examples"><a href="../Examples/doc/html/index.html">Examples</a></li> + <li class="SENFSCons"><a href="../senfscons/doc/html/index.html">SENFSCons</a></li> + </ul> + </div> + + <div class="tabs"> + <ul> + <li><a href="xref.html">Open Issues</a></li> + <li><a href="http://svn.berlios.de/wsvn/senf/?op=log&rev=0&sc=0&isdir=1">SVN ChangeLog</a></li> + <li><a href="http://developer.berlios.de/projects/senf">SENF @ BerliOS</a></li> + <li><a href="http://openfacts.berlios.de/index-en.phtml?title=SENF+Network+Framework">Wiki</a></li> + </ul> + </div> + + <!-- Generated by Doxygen 1.4.7 --> + <div class="tabs"> + <ul> + <li><a href="index.html"><span>Main Page</span></a></li> + <li><a href="pages.html"><span>Related Pages</span></a></li> + <hr style="width:0px;border:none;clear:both;margin:0;padding:0" /> + </div> + + <?php search(); ?> + + <hr style="width:0px;border:none;clear:both;margin:0;padding:0" /> + </div> +</div> +<div id="footer"> + <span> + <a href="mailto:senf-dev@lists.berlios.de">Contact: senf-dev@lists.berlios.de</a> | + Copyright © 2006 Fraunhofer Gesellschaft, SatCom, Stefan Bund + </span> +</div> + +</body></html> diff --git a/doclib/search_functions.php b/doclib/search_functions.php new file mode 100644 index 0000000000000000000000000000000000000000..0431d0cb96bba9031e9b30ee9d93aa9893d5b458 --- /dev/null +++ b/doclib/search_functions.php @@ -0,0 +1,381 @@ +<?php + +function search_results() +{ + return "Search Results"; +} + +function matches_text($num) +{ + if ($num==0) + { + return "Sorry, no documents matching your query."; + } + else if ($num==1) + { + return "Found <b>1</b> document matching your query."; + } + else // $num>1 + { + return "Found <b>$num</b> documents matching your query. Showing best matches first."; + } +} + +function report_matches() +{ + return "Matches: "; +} +function inputfield() +{ + $query=""; + if (array_key_exists("query", $_GET)) + { + $query=$_GET["query"]; + } + echo "<input type=\"text\" name=\"query\" value=\"$query\" size=\"20\" accesskey=\"s\"/>"; +} + +function readInt($file) +{ + $b1 = ord(fgetc($file)); $b2 = ord(fgetc($file)); + $b3 = ord(fgetc($file)); $b4 = ord(fgetc($file)); + return ($b1<<24)|($b2<<16)|($b3<<8)|$b4; +} + +function readString($file) +{ + $result=""; + while (ord($c=fgetc($file))) $result.=$c; + return $result; +} + +function readHeader($file) +{ + $header =fgetc($file); $header.=fgetc($file); + $header.=fgetc($file); $header.=fgetc($file); + return $header; +} + +function computeIndex($word) +{ + // Fast string hashing + //$lword = strtolower($word); + //$l = strlen($lword); + //for ($i=0;$i<$l;$i++) + //{ + // $c = ord($lword{$i}); + // $v = (($v & 0xfc00) ^ ($v << 6) ^ $c) & 0xffff; + //} + //return $v; + + // Simple hashing that allows for substring search + if (strlen($word)<2) return -1; + // high char of the index + $hi = ord($word{0}); + if ($hi==0) return -1; + // low char of the index + $lo = ord($word{1}); + if ($lo==0) return -1; + // return index + return $hi*256+$lo; +} + +function do_search($path, $file,$word,&$statsList) +{ + $index = computeIndex($word); + if ($index!=-1) // found a valid index + { + fseek($file,$index*4+4); // 4 bytes per entry, skip header + $index = readInt($file); + if ($index) // found words matching the hash key + { + $start=sizeof($statsList); + $count=$start; + fseek($file,$index); + $w = readString($file); + while ($w) + { + $statIdx = readInt($file); + if ($word==substr($w,0,strlen($word))) + { // found word that matches (as substring) + $statsList[$count++]=array( + "word"=>$word, + "match"=>$w, + "index"=>$statIdx, + "full"=>strlen($w)==strlen($word), + "docs"=>array() + ); + } + $w = readString($file); + } + $totalHi=0; + $totalFreqHi=0; + $totalFreqLo=0; + for ($count=$start;$count<sizeof($statsList);$count++) + { + $statInfo = &$statsList[$count]; + $multiplier = 1; + // whole word matches have a double weight + if ($statInfo["full"]) $multiplier=2; + fseek($file,$statInfo["index"]); + $numDocs = readInt($file); + $docInfo = array(); + // read docs info + occurrence frequency of the word + for ($i=0;$i<$numDocs;$i++) + { + $idx=readInt($file); + $freq=readInt($file); + $docInfo[$i]=array("idx" => $idx, + "freq" => $freq>>1, + "rank" => 0.0, + "hi" => $freq&1 + ); + if ($freq&1) // word occurs in high priority doc + { + $totalHi++; + $totalFreqHi+=$freq*$multiplier; + } + else // word occurs in low priority doc + { + $totalFreqLo+=$freq*$multiplier; + } + } + // read name and url info for the doc + for ($i=0;$i<$numDocs;$i++) + { + fseek($file,$docInfo[$i]["idx"]); + $docInfo[$i]["name"]=readString($file); + $docInfo[$i]["url"]=$path.readString($file); + } + $statInfo["docs"]=$docInfo; + } + $totalFreq=($totalHi+1)*$totalFreqLo + $totalFreqHi; + for ($count=$start;$count<sizeof($statsList);$count++) + { + $statInfo = &$statsList[$count]; + $multiplier = 1; + // whole word matches have a double weight + if ($statInfo["full"]) $multiplier=2; + for ($i=0;$i<sizeof($statInfo["docs"]);$i++) + { + $docInfo = &$statInfo["docs"]; + // compute frequency rank of the word in each doc + $freq=$docInfo[$i]["freq"]; + if ($docInfo[$i]["hi"]) + { + $statInfo["docs"][$i]["rank"]= + (float)($freq*$multiplier+$totalFreqLo)/$totalFreq; + } + else + { + $statInfo["docs"][$i]["rank"]= + (float)($freq*$multiplier)/$totalFreq; + } + } + } + } + } + return $statsList; +} + +function combine_results($results,&$docs) +{ + foreach ($results as $wordInfo) + { + $docsList = &$wordInfo["docs"]; + foreach ($docsList as $di) + { + $key=$di["url"]; + $rank=$di["rank"]; + if (in_array($key, array_keys($docs))) + { + $docs[$key]["rank"]+=$rank; + } + else + { + $docs[$key] = array("url"=>$key, + "name"=>$di["name"], + "rank"=>$rank + ); + } + $docs[$key]["words"][] = array( + "word"=>$wordInfo["word"], + "match"=>$wordInfo["match"], + "freq"=>$di["freq"] + ); + } + } + return $docs; +} + +function filter_results($docs,&$requiredWords,&$forbiddenWords) +{ + $filteredDocs=array(); + while (list ($key, $val) = each ($docs)) + { + $words = &$docs[$key]["words"]; + $copy=1; // copy entry by default + if (sizeof($requiredWords)>0) + { + foreach ($requiredWords as $reqWord) + { + $found=0; + foreach ($words as $wordInfo) + { + $found = $wordInfo["word"]==$reqWord; + if ($found) break; + } + if (!$found) + { + $copy=0; // document contains none of the required words + break; + } + } + } + if (sizeof($forbiddenWords)>0) + { + foreach ($words as $wordInfo) + { + if (in_array($wordInfo["word"],$forbiddenWords)) + { + $copy=0; // document contains a forbidden word + break; + } + } + } + if ($copy) $filteredDocs[$key]=$docs[$key]; + } + return $filteredDocs; +} + +function compare_rank($a,$b) +{ + if ($a["rank"] == $b["rank"]) + { + return 0; + } + return ($a["rank"]>$b["rank"]) ? -1 : 1; +} + +function sort_results($docs,&$sorted) +{ + $sorted = $docs; + usort($sorted,"compare_rank"); + return $sorted; +} + +function report_results(&$docs) +{ + echo "<table cellspacing=\"2\">\n"; + echo " <tr>\n"; + echo " <td colspan=\"2\"><h2>".search_results()."</h2></td>\n"; + echo " </tr>\n"; + $numDocs = sizeof($docs); + if ($numDocs==0) + { + echo " <tr>\n"; + echo " <td colspan=\"2\">".matches_text(0)."</td>\n"; + echo " </tr>\n"; + } + else + { + echo " <tr>\n"; + echo " <td colspan=\"2\">".matches_text($numDocs); + echo "\n"; + echo " </td>\n"; + echo " </tr>\n"; + $num=1; + foreach ($docs as $doc) + { + echo " <tr>\n"; + echo " <td align=\"right\">$num.</td>"; + echo "<td><a class=\"el\" href=\"".$doc["url"]."\">".$doc["name"]."</a></td>\n"; + echo " <tr>\n"; + echo " <td></td><td class=\"tiny\">".report_matches()." "; + foreach ($doc["words"] as $wordInfo) + { + $word = $wordInfo["word"]; + $matchRight = substr($wordInfo["match"],strlen($word)); + echo "<b>$word</b>$matchRight(".$wordInfo["freq"].") "; + } + echo " </td>\n"; + echo " </tr>\n"; + $num++; + } + } + echo "</table>\n"; +} + +function search() +{ + if(strcmp('4.1.0', phpversion()) > 0) + { + die("Error: PHP version 4.1.0 or above required!"); + } + + $paths = array( + "../doc/html/", + "../Socket/doc/html/", + "../Examples/doc/html/", + "../Packets/doc/html/", + "../Utils/doc/html/", + "../Scheduler/doc/html/", + ); + $files = array(); + $j=0; + for ($i=0; $i<sizeof($paths); $i++) { + if (!($f=@fopen($paths[$i]."search.idx","rb"))) + { + die("Error: Search index file could NOT be opened!"); + continue; + } + $files[$j++] = $f; + if (readHeader($f)!="DOXS") + { + die("Error: Header of index file is invalid!"); + } + } + + $query=""; + if (array_key_exists("query", $_GET)) + { + $query=$_GET["query"]; + } + //end_form($query); + echo " \n<div class=\"searchresults\">\n"; + $results = array(); + $requiredWords = array(); + $forbiddenWords = array(); + $foundWords = array(); + $word=strtok($query," "); + while ($word) // for each word in the search query + { + if (($word{0}=='+')) { $word=substr($word,1); $requiredWords[]=$word; } + if (($word{0}=='-')) { $word=substr($word,1); $forbiddenWords[]=$word; } + if (!in_array($word,$foundWords)) + { + $foundWords[]=$word; + for ($i=0; $i<sizeof($files); $i++) { + do_search($paths[$i], $files[$i], strtolower($word), $results); + } + } + $word=strtok(" "); + } + $docs = array(); + combine_results($results,$docs); + // filter out documents with forbidden word or that do not contain + // required words + $filteredDocs = filter_results($docs,$requiredWords,$forbiddenWords); + // sort the results based on rank + $sorted = array(); + sort_results($filteredDocs,$sorted); + // report results to the user + report_results($sorted); + echo "</div>\n"; + foreach ($files as $file) { + fclose($file); + } +} + + +?> diff --git a/doclib/senf.css b/doclib/senf.css index d8292becb76e17f116f512659c5e382f73016649..5e3c48082c2c93ea1c363bf92009827277873a73 100644 --- a/doclib/senf.css +++ b/doclib/senf.css @@ -5,7 +5,7 @@ body { } #head { - height: 62px; + height: 72px; border-top: 5px solid #DECD40; border-bottom: 1px solid #AF9D00; background: url(logo-head.png) top left no-repeat; @@ -27,8 +27,8 @@ body { #head h2 { margin: 0 0 0 100px; - padding: 4px 0 0 42px; - height: 18px; + padding: 6px 0 0 42px; + height: 26px; background-color: #EDE497; color: #726921; font-size: 13px; @@ -36,6 +36,12 @@ body { white-space: nowrap; } +#search { + position: absolute; + top: 50px; + right: 10px; +} + #content1 { padding: 0 10px 10px 0; border-bottom: 1px solid #AF9D00;