from enum import Flag
from types import SimpleNamespace as Empty
+searchdata_format_version = 0
+searchdata_filename = f'searchdata-v{searchdata_format_version}.bin'
+searchdata_filename_b85 = f'searchdata-v{searchdata_format_version}.js'
+
class ResultFlag(Flag):
@staticmethod
def from_type(flag: 'ResultFlag', type) -> 'ResultFlag':
serialized_trie = trie.serialize(merge_subtrees=merge_subtrees)
serialized_map = map.serialize(merge_prefixes=merge_prefixes)
# magic header, version, symbol count, offset of result map
- return search_data_header_struct.pack(b'MCS', 0, symbol_count, len(serialized_trie) + 10) + serialized_trie + serialized_map
+ return search_data_header_struct.pack(b'MCS', searchdata_format_version, symbol_count, len(serialized_trie) + 10) + serialized_trie + serialized_map
def base85encode_search_data(data: bytearray) -> bytearray:
return (b"/* Generated by https://mcss.mosra.cz/documentation/doxygen/. Do not edit. */\n" +
def pretty_print(serialized: bytes, *, entryTypeClass, show_merged=False, show_lookahead_barriers=True, colors=False):
magic, version, symbol_count, map_offset = search_data_header_struct.unpack_from(serialized)
assert magic == b'MCS'
- assert version == 0
+ assert version == searchdata_format_version
pretty_trie, stats = pretty_print_trie(serialized[search_data_header_struct.size:map_offset], show_merged=show_merged, show_lookahead_barriers=show_lookahead_barriers, colors=colors)
pretty_map = pretty_print_map(serialized[map_offset:], entryTypeClass=entryTypeClass, colors=colors)
from pygments.formatters import HtmlFormatter
from pygments.lexers import TextLexer, BashSessionLexer, get_lexer_by_name, find_lexer_class_for_filename
-from _search import ResultFlag, ResultMap, Trie, serialize_search_data, base85encode_search_data
+from _search import ResultFlag, ResultMap, Trie, serialize_search_data, base85encode_search_data, searchdata_filename, searchdata_filename_b85, searchdata_format_version
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../plugins'))
import dot2svg
rendered = template.render(index=parsed.index,
DOXYGEN_VERSION=parsed.version,
FILENAME=file,
+ SEARCHDATA_FORMAT_VERSION=searchdata_format_version,
**state.doxyfile)
output = os.path.join(html_output, file)
rendered = template.render(compound=parsed.compound,
DOXYGEN_VERSION=parsed.version,
FILENAME=parsed.compound.url,
+ SEARCHDATA_FORMAT_VERSION=searchdata_format_version,
**state.doxyfile)
output = os.path.join(html_output, parsed.compound.url)
rendered = template.render(compound=compound,
DOXYGEN_VERSION='0',
FILENAME='index.html',
+ SEARCHDATA_FORMAT_VERSION=searchdata_format_version,
**state.doxyfile)
output = os.path.join(html_output, 'index.html')
with open(output, 'wb') as f:
data = build_search_data(state, add_lookahead_barriers=search_add_lookahead_barriers, merge_subtrees=search_merge_subtrees, merge_prefixes=search_merge_prefixes)
if state.doxyfile['M_SEARCH_DOWNLOAD_BINARY']:
- with open(os.path.join(html_output, "searchdata.bin"), 'wb') as f:
+ with open(os.path.join(html_output, searchdata_filename), 'wb') as f:
f.write(data)
else:
- with open(os.path.join(html_output, "searchdata.js"), 'wb') as f:
+ with open(os.path.join(html_output, searchdata_filename_b85), 'wb') as f:
f.write(base85encode_search_data(data))
# OpenSearch metadata, in case we have the base URL
import jinja2
+from _search import searchdata_format_version
+
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../plugins'))
import m.htmlsanity
def render(config, template: str, page, env: jinja2.Environment):
template = env.get_template(template)
- rendered = template.render(page=page, URL=page.url, **config)
+ rendered = template.render(page=page,
+ URL=page.url,
+ SEARCHDATA_FORMAT_VERSION=searchdata_format_version, **config)
with open(os.path.join(config['OUTPUT'], page.filename), 'wb') as f:
f.write(rendered.encode('utf-8'))
# Add back a trailing newline so we don't need to bother with
"use strict"; /* it summons the Cthulhu in a proper way, they say */
var Search = {
+ formatVersion: 0, /* the data filename contains this number too */
+
trie: null,
map: null,
dataSize: 0,
return false;
}
- if(view.getUint8(3) != 0) {
+ if(view.getUint8(3) != this.formatVersion) {
console.error("Invalid search data version");
return false;
}
return true;
},
- download: /* istanbul ignore next */ function(url) {
+ download: /* istanbul ignore next */ function(urlBase) {
var req = window.XDomainRequest ? new XDomainRequest() : new XMLHttpRequest();
if(!req) return;
- req.open("GET", url, true);
+ req.open("GET", urlBase + "searchdata-v" + this.formatVersion + ".bin", true);
req.responseType = 'arraybuffer';
req.onreadystatechange = function() {
if(req.readyState != 4) return;
<script src="search.js"></script>
{% if M_SEARCH_DOWNLOAD_BINARY %}
<script>
- Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1) + "searchdata.bin");
+ Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1));
</script>
{% else %}
-<script src="searchdata.js" async="async"></script>
+<script src="searchdata-v{{ SEARCHDATA_FORMAT_VERSION }}.js" async="async"></script>
{% endif %}
{% endif %}
{% if M_PAGE_FINE_PRINT %}
{#- sanity checks for variables that should be always defined -#}
{% if FILENAME is not defined %}{{ FILENAME.is_not_defined_the_script_is_broken }}{% endif %}
{% if DOXYGEN_VERSION is not defined %}{{ DOXYGEN_VERSION.is_not_defined_the_script_is_broken }}{% endif %}
+{% if SEARCHDATA_FORMAT_VERSION is defined %}{{ SEARCHDATA_FORMAT_VERSION.is_not_defined_the_script_is_broken }}{% endif %}
<script src="search.js"></script>
{% if SEARCH_DOWNLOAD_BINARY %}
<script>
- Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1) + "searchdata.bin");
+ Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1));
</script>
{% else %}
-<script src="searchdata.js" async="async"></script>
+<script src="searchdata-v{{ SEARCHDATA_FORMAT_VERSION }}.js" async="async"></script>
{% endif %}
{% endif %}
{% if FINE_PRINT %}
</html>
{#- sanity checks for variables that should be always defined -#}
{% if URL is not defined %}{{ URL.is_not_defined_the_script_is_broken }}{% endif %}
+{% if SEARCHDATA_FORMAT_VERSION is defined %}{{ SEARCHDATA_FORMAT_VERSION.is_not_defined_the_script_is_broken }}{% endif %}
</div>
</div>
<script src="search.js"></script>
-<script src="searchdata.js" async="async"></script>
+<script src="searchdata-v0.js" async="async"></script>
<footer><nav>
<div class="m-container">
<div class="m-row">
</div>
</div>
<script src="search.js"></script>
-<script src="searchdata.js" async="async"></script>
+<script src="searchdata-v0.js" async="async"></script>
<footer><nav>
<div class="m-container">
<div class="m-row">
</div>
</div>
<script src="search.js"></script>
-<script src="searchdata.js" async="async"></script>
+<script src="searchdata-v0.js" async="async"></script>
<footer><nav>
<div class="m-container">
<div class="m-row">
</div>
<script src="search.js"></script>
<script>
- Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1) + "searchdata.bin");
+ Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1));
</script>
</body>
</html>
</div>
</div>
<script src="search.js"></script>
-<script src="searchdata.js" async="async"></script>
+<script src="searchdata-v0.js" async="async"></script>
</body>
</html>
import os
import subprocess
+from _search import searchdata_filename, searchdata_filename_b85
from . import BaseTestCase
class Layout(BaseTestCase):
self.assertEqual(*self.actual_expected_contents('pages.html'))
self.assertTrue(os.path.exists(os.path.join(self.path, 'html', 'm-dark+documentation.compiled.css')))
self.assertTrue(os.path.exists(os.path.join(self.path, 'html', 'search.js')))
- self.assertTrue(os.path.exists(os.path.join(self.path, 'html', 'searchdata.js')))
+ self.assertTrue(os.path.exists(os.path.join(self.path, 'html', searchdata_filename_b85)))
self.assertTrue(os.path.exists(os.path.join(self.path, 'html', 'favicon-light.png')))
class GeneratedDoxyfile(BaseTestCase):
def test(self):
self.run_doxygen(wildcard='indexpage.xml')
self.assertEqual(*self.actual_expected_contents('index.html'))
- self.assertTrue(os.path.exists(os.path.join(self.path, 'html', 'searchdata.bin')))
+ self.assertTrue(os.path.exists(os.path.join(self.path, 'html', searchdata_filename)))
class SearchOpenSearch(BaseTestCase):
def __init__(self, *args, **kwargs):
from types import SimpleNamespace as Empty
from doxygen import EntryType
-from _search import Trie, ResultMap, ResultFlag, serialize_search_data, pretty_print_trie, pretty_print_map, pretty_print
+from _search import Trie, ResultMap, ResultFlag, serialize_search_data, pretty_print_trie, pretty_print_map, pretty_print, searchdata_filename
from test_doxygen import IntegrationTestCase
def test(self):
self.run_doxygen(index_pages=[], wildcard='*.xml')
- with open(os.path.join(self.path, 'html', 'searchdata.bin'), 'rb') as f:
+ with open(os.path.join(self.path, 'html', searchdata_filename), 'rb') as f:
serialized = f.read()
search_data_pretty = pretty_print(serialized, entryTypeClass=EntryType)[0]
#print(search_data_pretty)
def test(self):
self.run_doxygen(index_pages=[], wildcard='*.xml')
- with open(os.path.join(self.path, 'html', 'searchdata.bin'), 'rb') as f:
+ with open(os.path.join(self.path, 'html', searchdata_filename), 'rb') as f:
serialized = f.read()
search_data_pretty = pretty_print(serialized, entryTypeClass=EntryType)[0]
#print(search_data_pretty)
import os
-from _search import search_data_header_struct
+from _search import search_data_header_struct, searchdata_filename
from . import IntegrationTestCase
# Test we have all symbols in search data. It's enough to assert the
# count, it equal to symbol count in the header file
# TODO: reuse the search data deserialization API once done
- with open(os.path.join(self.path, 'html', 'searchdata.bin'), 'rb') as f:
+ with open(os.path.join(self.path, 'html', searchdata_filename), 'rb') as f:
serialized = f.read()
magic, version, symbol_count, map_offset = search_data_header_struct.unpack_from(serialized)
self.assertEqual(symbol_count, 44)
</div>
<script src="search.js"></script>
<script>
- Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1) + "searchdata.bin");
+ Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1));
</script>
</body>
</html>
</div>
<script src="search.js"></script>
<script>
- Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1) + "searchdata.bin");
+ Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1));
</script>
</body>
</html>
</div>
<script src="search.js"></script>
<script>
- Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1) + "searchdata.bin");
+ Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1));
</script>
</body>
</html>
</div>
<script src="search.js"></script>
<script>
- Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1) + "searchdata.bin");
+ Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1));
</script>
</body>
</html>
</div>
<script src="search.js"></script>
<script>
- Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1) + "searchdata.bin");
+ Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1));
</script>
</body>
</html>
</div>
<script src="search.js"></script>
<script>
- Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1) + "searchdata.bin");
+ Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1));
</script>
</body>
</html>
</div>
<script src="search.js"></script>
<script>
- Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1) + "searchdata.bin");
+ Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1));
</script>
</body>
</html>
</div>
<script src="search.js"></script>
<script>
- Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1) + "searchdata.bin");
+ Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1));
</script>
</body>
</html>
</div>
</div>
<script src="search.js"></script>
-<script src="searchdata.js" async="async"></script>
+<script src="searchdata-v0.js" async="async"></script>
<footer><nav>
<div class="m-container">
<div class="m-row">