blob: 41f3700877deea637755ed8d9064f1ac34083aee [file]
# **********************************************************
# Copyright (c) 2011-2021 Google, Inc. All rights reserved.
# Copyright (c) 2009-2010 VMware, Inc. All rights reserved.
# **********************************************************
# Dr. Memory: the memory debugger
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation;
# version 2.1 of the License, and no later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
###########################################################################
# Usage:
# + Add a custom command to invoke this script in the docs build dir
# + Assumes a favicon.ico is present in the target build dir
#
# Args:
# + DOXYGEN_EXECUTABLE : path to doxygen
# + doxygen_ver : version of doxygen
# + version_number : version number to put in the docs
# + module_string_long : replacement text for Modules
# + module_string_short : replacement text for Module
# + files_string : replacement text for Files; optional
# + structs_string : replacement text for Data Structures; optional
# + home_url : home page URL
# + home_title : home page title
# + logo_imgfile : image file with logo
# + embeddable : whether to edit content for jekyll embedding
# + proj_srcdir : project base source dir, for editing titles
# + proj_bindir : project base binary dir, for editing titles
#
###########################################################################
# Any quotes carry over and it's simplest to assume not there.
string(REPLACE "\"" "" module_string_long ${module_string_long})
string(REPLACE "\"" "" module_string_short ${module_string_short})
if (DEFINED files_string)
string(REPLACE "\"" "" files_string ${files_string})
endif ()
if (DEFINED structs_string)
string(REPLACE "\"" "" structs_string ${structs_string})
endif ()
string(REPLACE "\"" "" home_url ${home_url})
string(REPLACE "\"" "" home_title ${home_title})
string(REPLACE "\"" "" logo_imgfile ${logo_imgfile})
# First, generate header.html and footer.html suitable for current
# doxygen version and then tweak them.
# Note that we must generate a css file and we must name it doxygen.css
# or else we have to later copy it to html dir.
execute_process(COMMAND
${DOXYGEN_EXECUTABLE} -w html header.html footer.html doxygen.css
RESULT_VARIABLE doxygen_w_result
ERROR_VARIABLE doxygen_w_error
OUTPUT_QUIET
)
if (doxygen_w_result OR doxygen_w_error)
message(FATAL_ERROR "*** ${DOXYGEN_EXECUTABLE} failed: ***\n${doxygen_w_error}")
endif (doxygen_w_result OR doxygen_w_error)
# Add favicon to header
file(READ ${CMAKE_CURRENT_BINARY_DIR}/header.html string)
string(REGEX REPLACE
"<title>"
"<link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"favicon.ico\"/>\n<title>"
string "${string}")
if (doxygen_ver VERSION_LESS "1.7.0")
# For some reason older doxygen doesn't replace its own vars w/ custom header
string(REGEX REPLACE "\\$relpath\\$" "" string "${string}")
endif ()
if (embeddable)
# Add jekyll header.
set(string "---
title: \"$title\"
layout: default
---
${string}")
endif ()
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/header.html "${string}")
# Tweak footer to have version
file(READ ${CMAKE_CURRENT_BINARY_DIR}/footer.html string)
set(foot "<img border=0 src=\"favicon.png\"> &nbsp; ")
set(foot "${foot} $projectname version ${version_number} --- $datetime")
set(foot "${foot} &nbsp; <img border=0 src=\"favicon.png\">")
# Recent doxygen
string(REGEX REPLACE "\\$generated.*doxygenversion" "${foot}" string "${string}")
# Older doxygen
string(REGEX REPLACE "Generated.*doxygenversion" "${foot}" string "${string}")
# Prefer center to default float:right
string(REGEX REPLACE "class=\"footer\""
"class=\"footer\" style=\"float:none;text-align:center\""
string "${string}")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/footer.html "${string}")
if (doxygen_ver STRGREATER "1.7.2")
# Create a layout file so we can control the treeview index
execute_process(COMMAND
${DOXYGEN_EXECUTABLE} -l
RESULT_VARIABLE doxygen_l_result
ERROR_VARIABLE doxygen_l_error
OUTPUT_QUIET
)
if (doxygen_l_result OR doxygen_l_error)
message(FATAL_ERROR "*** ${DOXYGEN_EXECUTABLE} failed: ***\n${doxygen_l_error}")
endif (doxygen_l_result OR doxygen_l_error)
file(READ ${CMAKE_CURRENT_BINARY_DIR}/DoxygenLayout.xml string)
# Rename "Modules" (done below for older doxygen)
string(REGEX REPLACE
"tab type=\"modules\" visible=\"yes\" title=\"\""
"tab type=\"modules\" visible=\"yes\" title=\"${module_string_long}\""
string "${string}")
if (doxygen_ver STRGREATER "1.7.5")
# Add link to home page (done below for older doxygen; skipped for 1.7.3-1.7.5)
string(REGEX REPLACE
"</navindex>"
"<tab type=\"user\" url=\"${home_url}\" title=\"${home_title}\"/>\n</navindex>"
string "${string}")
endif ()
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/DoxygenLayout.xml "${string}")
endif ()
# Run doxygen and fail on warnings.
# Now update to latest doxygen. Suppress warnings since they're misleading:
# they say "please run doxygen -u" but we're currently doing just that.
execute_process(COMMAND
${DOXYGEN_EXECUTABLE}
RESULT_VARIABLE doxygen_u_result
ERROR_VARIABLE doxygen_u_error
OUTPUT_QUIET
)
if (doxygen_u_result OR doxygen_u_error)
message(FATAL_ERROR "*** ${DOXYGEN_EXECUTABLE} failed: ***\n${doxygen_u_error}")
endif (doxygen_u_result OR doxygen_u_error)
# Doxygen does not put header.html on the top-level frame so we add favicon manually
file(READ ${CMAKE_CURRENT_BINARY_DIR}/html/index.html string)
string(REGEX REPLACE
"<title>"
"<link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"favicon.ico\"/>\n<title>"
string "${string}")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/html/index.html "${string}")
if (embeddable)
# We need to make some edits for insertion into our jekyll site.
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/html/keywords.js "---\nlayout: null\n---\n")
file(GLOB all_html ${CMAKE_CURRENT_BINARY_DIR}/html/*.html)
foreach (html ${all_html})
file(READ ${html} string)
# Remove headers and body tag.
string(REGEX REPLACE "<!-- HTML header.*<body>\n" "" string "${string}")
# Remove body and html close tags.
string(REGEX REPLACE "</body>.*</html>\n" "" string "${string}")
# Remove full paths.
string(REGEX REPLACE "\ntitle: \"${proj_bindir}" "\ntitle: \"" string "${string}")
string(REGEX REPLACE "\ntitle: \"${proj_srcdir}" "\ntitle: \"" string "${string}")
# Add permalink to front matter so the web site hides the docs/ subdir.
get_filename_component(linkname ${html} NAME)
string(REGEX REPLACE "(\nlayout: default\n)" "\\1permalink: /${linkname}\n"
string "${string}")
# Our images are in an images/ subdir.
string(REGEX REPLACE "<img src=\"" "<img src=\"/images/" string "${string}")
# Collect type info for keyword searches with direct anchor links (else the
# search finds the page but the user then has to manually search within the long
# page -- and there are no doygen options to split each onto its own page).
# The format here is the javascript object used by search.js to set up lunr.
# XXX: This is fragile and highly dependent on the precise doxygen output.
get_filename_component(fname ${html} NAME_WE)
# The ;'s mess up the MATCHALL results so we remove them.
string(REPLACE ";" "_" nosemis "${string}")
string(REGEX MATCHALL "<tr class=\"memitem[^\n]*</tr>" types "${nosemis}")
foreach (type ${types})
string(REGEX MATCH "href=\"[^\"]+\"" url "${type}")
string(REGEX REPLACE "href=\"([^\"]+)\"" "\\1" url "${url}")
string(REGEX MATCH "\">[_a-zA-Z0-9]+</a>" name "${type}")
string(REGEX REPLACE "\">([_a-zA-Z0-9]+)</a>" "\\1" name "${name}")
if (name STREQUAL "")
continue ()
endif ()
# Support searching by partial names.
set(extra "")
string(REPLACE "_" " " separate "${name}")
if (NOT separate STREQUAL name)
set(extra "${extra} ${separate}")
endif ()
set(prefix "${name}")
while (prefix MATCHES "[^_]_[^_]")
string(REGEX REPLACE "_[^_]*$" "" prefix "${prefix}")
set(extra "${extra} ${prefix}")
endwhile ()
set(keywords "window.data[\"${fname}-${name}\"]={\
\"name\":\"${fname}-${name}\",\
\"title\":\"${name} in ${fname} header\",\
\"url\":\"${url}\",\
\"content\":\"${name} ${extra}\"};\n")
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/html/keywords.js "${keywords}")
endforeach ()
# Similarly, put in explicit search entries for sections so searches go
# straight to the anchor link.
string(REGEX MATCHALL "\n<h1><a class=\"anchor\" id=\"[^\"]*\"></a>\n[^\n]+</h1>"
sections "${nosemis}")
foreach (section ${sections})
string(REGEX REPLACE ".* id=\"([^\"]+)\".*" "\\1" id "${section}")
string(REGEX REPLACE ".*</a>\n([^<]+)</h1>" "\\1" name "${section}")
if (name STREQUAL "" OR id STREQUAL "" OR name MATCHES "<")
message(FATAL_ERROR "Failed to find section name or anchor: ${section}")
endif ()
set(url "/${fname}.html#${id}")
# Quotes cause JavaScript syntax errors.
string(REPLACE "\"" "" name "${name}")
# Spaces would be ok but it feels nicer w/o them in the key.
string(REPLACE " " "_" key "${name}")
set(keywords "window.data[\"${fname}-${key}\"]={\
\"name\":\"${fname}-${key}\",\
\"title\":\"${name}\",\
\"url\":\"${url}\",\
\"content\":\"${name}\"};\n")
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/html/keywords.js "${keywords}")
endforeach ()
file(WRITE ${html} "${string}")
endforeach ()
# We leverage the javascript menu from the non-embedded version.
file(GLOB all_js ${CMAKE_CURRENT_BINARY_DIR}/../html/*.js)
set(found_user_docs OFF)
foreach (js ${all_js})
if (js MATCHES "navtree.js" OR
js MATCHES "resize.js" OR
js MATCHES "navtreeindex")
continue ()
endif ()
file(READ ${js} string)
# Ask jekyll to inline, instead of just naming for JS.
string(REGEX REPLACE ", \"([^\"]+)\" \\]" ", {% include_relative \\1.js %} ]"
string "${string}")
if (js MATCHES "navtreedata.js")
# Add a jekyll header.
set(string "---\npermalink: /navtreedata.js\n---\n${string}")
# Remove the index array from navtreedata.js.
string(REGEX REPLACE "var NAVTREEINDEX =[^;]*;" "" string "${string}")
# Remove one layer from navtreedata.js.
string(REGEX REPLACE "\n *\\[ \"Dr. Memory\", \"index.html\", \\[" ""
string "${string}")
# Remove the home page at the end.
string(REGEX REPLACE "\n[^\n]*Dr. Memory Home Page[^\n]*\n" "" string "${string}")
# Insert a layer in navtreedata.js, using the end of the top layer we removed.
string(REGEX REPLACE "\n( *\\[ \"Deprecated List)"
"\n[ \"API Reference\", \"files.html\", [\n\\1"
string "${string}")
else ()
# Remove name so we can inline.
string(REGEX REPLACE "var [^\n]* =\n" "" string "${string}")
# End in a comma for inlining.
string(REGEX REPLACE "\\];" "]," string "${string}")
# Update directory index names which are hashes that differ between the
# treeview and embed generations.
string(REGEX MATCHALL "\"[a-zA-Z_0-9]+\", \"dir_[a-f0-9]+\\.html\""
dir_hashes "${string}")
foreach (dir_hash ${dir_hashes})
string(REGEX REPLACE "\"([a-zA-Z_0-9]+)\".*" "\\1" key "${dir_hash}")
# We go search the dir_*.html embed files looking for key.
file(GLOB dir_html ${CMAKE_CURRENT_BINARY_DIR}/html/dir_*.html)
set(found_hash OFF)
foreach (html ${dir_html})
file(READ ${html} html_string)
if (html_string MATCHES "${key} Directory Reference")
get_filename_component(fname ${html} NAME)
string(REGEX REPLACE "\"${key}\", \"dir_[a-f0-9]+\\.html\""
"\"${key}\", \"${fname}\"" string "${string}")
set(found_hash ON)
break ()
endif ()
endforeach ()
if (NOT found_hash)
message(FATAL_ERROR "Cannot find corresonding page for ${key}")
endif ()
endforeach ()
endif ()
# Put the modified contents into our dir.
get_filename_component(fname ${js} NAME)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/html/${fname} "${string}")
endforeach ()
else ()
# Edit navbar.
if (doxygen_ver VERSION_LESS "1.7.3")
# Add link to home page to treeview pane
file(APPEND
${CMAKE_CURRENT_BINARY_DIR}/html/tree.html
"<p>&nbsp;<a target=\"main\" href=\"${home_url}/\">${home_title}</a></p>")
# Add our logo to treeview pane (yes there is no closing </body></html>)
file(APPEND
${CMAKE_CURRENT_BINARY_DIR}/html/tree.html
"<p>&nbsp;<br><img src=\"${logo_imgfile}\"></p>")
else ()
# This is a fragile insertion into the javascript used for the navbar.
# We insert at the end of the final function (initNavTree).
# This works in doxygen 1.7.4-1.8.1.
set(add_logo "
var imgdiv = document.createElement(\"div\");
document.getElementById(\"nav-tree-contents\").appendChild(imgdiv);
var img = document.createElement(\"img\");
imgdiv.appendChild(img);
img.src = \"${logo_imgfile}\";
img.style.marginLeft = \"80px\";
img.style.marginTop = \"30px\";
")
file(READ ${CMAKE_CURRENT_BINARY_DIR}/html/navtree.js string)
string(REGEX REPLACE
"\\}\n*$"
"${add_logo}\n}"
string "${string}")
# Doxygen 1.9.1 has this license-end line.
string(REGEX REPLACE
"\\}\n/\\* @license-end \\*/\n$"
"${add_logo}\n}"
string "${string}")
# While we're here we replace Files and Data Structures, if requested
if (DEFINED files_string)
string(REGEX REPLACE "\"Files\"" "\"${files_string}\"" string "${string}")
endif ()
if (DEFINED structs_string)
string(REGEX REPLACE "\"Data Structures\"" "\"${structs_string}\""
string "${string}")
endif ()
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/html/navtree.js "${string}")
endif ()
endif ()
# For modules/extensions (i#277/PR 540817) we use doxygen groups which show up under
# top-level "Modules" which we rename here
if (doxygen_ver VERSION_LESS "1.7.3")
file(READ ${CMAKE_CURRENT_BINARY_DIR}/html/tree.html string)
string(REGEX REPLACE "Modules" "${module_string_long}" string "${string}")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/html/tree.html "${string}")
endif ()
if (EXISTS ${CMAKE_CURRENT_BINARY_DIR}/html/modules.html)
file(READ ${CMAKE_CURRENT_BINARY_DIR}/html/modules.html string)
string(REGEX REPLACE "Module" "${module_string_short}" string "${string}")
string(REGEX REPLACE "module" "${module_string_short}" string "${string}")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/html/modules.html "${string}")
endif ()
# We do not copy samples or favicon for build dir: those are install rules