From a7cb088d475f43cad0eab3f002e245ee44d585f1 Mon Sep 17 00:00:00 2001 From: "Georgi (Joro) Kodinov" Date: Fri, 22 May 2026 16:22:17 +0300 Subject: [PATCH] MDEV-39718: Produce Markdown plugin API documentation Implemented a cmake utility macro to generate markdown documentation. Generated the plugin API headers. Fixed some doxygen comment mistakes in these. --- CMakeLists.txt | 4 + cmake/generated_docs.cmake | 110 ++++++++++++++++++++++++ include/CMakeLists.txt | 42 +++++++++ include/mysql/service_debug_sync.h | 4 +- include/mysql/service_logger.h | 2 +- include/mysql/service_my_snprintf.h | 19 ++-- include/mysql/service_progress_report.h | 2 +- include/mysql/service_thd_autoinc.h | 6 +- include/mysql/service_thd_rnd.h | 7 +- 9 files changed, 177 insertions(+), 19 deletions(-) create mode 100644 cmake/generated_docs.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d753c4e0e8c8..4a51f4cf2112f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -502,6 +502,10 @@ MARK_AS_ADVANCED(PYTHON_SHEBANG) # Add storage engines and plugins. CONFIGURE_PLUGINS() +# Find the documentation generation tools and add the DOCS_GENERATE macro +INCLUDE(${CMAKE_SOURCE_DIR}/cmake/generated_docs.cmake) +GENERATED_DOCS_FIND_PROGRAMS() + ADD_SUBDIRECTORY(include) ADD_SUBDIRECTORY(dbug) ADD_SUBDIRECTORY(strings) diff --git a/cmake/generated_docs.cmake b/cmake/generated_docs.cmake new file mode 100644 index 0000000000000..1ba4807e70b25 --- /dev/null +++ b/cmake/generated_docs.cmake @@ -0,0 +1,110 @@ +# Copyright (c) 2026, MariaDB Corporation +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA + +# Utilities to produce generated docs. The docs are generated as part of +# the build, but only if WITH_GENERATED_DOCS is set to ON. The docs are generated +# using doxygen and moxygen, and are output to the docs directory +# in the build directory. +# First doxygen is called to produce XML output into docs/${PROJECT}/xml, +# and then moxygen is called to produce markdown output into +# docs/${PROJECT}/$PROJECT.md out of the XML output. +# Normal usage sequence: +# * include this file in the top-level CMakeLists.txt +# * call GENERATED_DOCS_FIND_PROGRAMS immediately after +# to find the required programs +# * call DOCS_GENERATE for each project to generate docs for. + + +# An option to control building the generated docs. +# Possible values are: +# - ON: always build the docs or fail trying +# - OFF: do not build the docs +SET(WITH_GENERATED_DOCS OFF CACHE BOOL "Produce the generated docs") + + +# Macro to find the programs needed for generating the docs. +# This is to be called from the top-level CMakeLists.txt, and the results +# are used in the DOCS_GENERATE +MACRO(GENERATED_DOCS_FIND_PROGRAMS) + IF (WITH_GENERATED_DOCS) + FIND_PACKAGE(Doxygen REQUIRED) + FIND_PROGRAM(MOXYGEN_BIN moxygen OPTIONAL) + IF (NOT MOXYGEN_BIN) + MESSAGE(FATAL_ERROR "Moxygen is required to build the generated docs. See https://github.com/sourcey/moxygen/") + ENDIF() + ENDIF() +ENDMACRO() + +# Generate documentation for a project. +# There can be multiple projects, e.g. one for the plugin API, one for the server, etc. +# Creates a target named DOCS_${NAME} that generates the docs for the specified sources. +# Call with a project name name, a mask (default *), and list of sources, e.g. +# GENERATED_DOCS_PROJECT(NAME plugin_api MASK "*.h" foo.h bar.h) +# Note: GENERATED_DOCS_FIND_PROGRAMS must have been called before this. + +FUNCTION (GENERATED_DOCS_PROJECT) + + CMAKE_PARSE_ARGUMENTS(ARG + "" + "NAME;MASK" + "" + ${ARGN} + ) + IF (NOT ARG_NAME) + MESSAGE(FATAL_ERROR "NAME is required") + ENDIF() + STRING(FIND "${ARG_NAME}" " " _found_space) + IF(NOT _found_space EQUAL -1) + MESSAGE(FATAL_ERROR "NAME must not contain spaces") + ENDIF() + + IF (NOT ARG_MASK) + SET(ARG_MASK "*") + ENDIF() + + STRING(TOLOWER "${ARG_NAME}" DOCS_PROJECT_NAME) + STRING(PREPEND DOCS_PROJECT_NAME "generated_docs_") + ADD_FEATURE_INFO(${DOCS_PROJECT_NAME} WITH_GENERATED_DOCS "Generated documentation for the ${ARG_NAME}") + IF (NOT WITH_GENERATED_DOCS) + RETURN() + ENDIF() + + SET(SOURCES ${ARG_UNPARSED_ARGUMENTS}) + + FILE(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/docs) + FILE(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/docs/${ARG_NAME}) + FILE(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/docs/${ARG_NAME}/md) + + SET(DOXYGEN_FILE_PATTERNS ${ARG_MASK}) + SET(DOXYGEN_GENERATE_HTML NO) + SET(DOXYGEN_WARN_IF_UNDOCUMENTED NO) + SET(DOXYGEN_GENERATE_XML YES) + SET(DOXYGEN_INCLUDE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + SET(DOXYGEN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/docs/${ARG_NAME}") + SET(DOXYGEN_WARN_AS_ERROR YES) + SET(DOXYGEN_EXTRACT_ALL YES) + SET(DOXYGEN_QUIET YES) + SET(DOXYGEN_XML_PROGRAMLISTING YES) + doxygen_add_docs(${DOCS_PROJECT_NAME} ${SOURCES} ALL USE_STAMP_FILE COMMENT "Generating ${ARG_NAME} XML docs with doxygen") + ADD_CUSTOM_COMMAND(TARGET ${DOCS_PROJECT_NAME} POST_BUILD + COMMAND ${MOXYGEN_BIN} --quiet + --source-root ${CMAKE_SOURCE_DIR} + --output ${CMAKE_BINARY_DIR}/docs/${ARG_NAME}/md/${ARG_NAME}.md + ${CMAKE_BINARY_DIR}/docs/${ARG_NAME}/xml + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/docs/${ARG_NAME}/md + BYPRODUCTS ${CMAKE_BINARY_DIR}/docs/${ARG_NAME}/md/${ARG_NAME}.md + COMMENT "Generating ${ARG_NAME} markdown docs with moxygen" + ) +ENDFUNCTION() \ No newline at end of file diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 1cc6459d59ac0..13d7ae95f6366 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -121,3 +121,45 @@ INSTALL_COMPAT_HEADER(mysql_version.h " INSTALL_COMPAT_HEADER(mysql_com.h " #include ") + +SET(PLUGIN_API_HEADERS + mysql/plugin.h + mysql/plugin_audit.h + mysql/plugin_auth.h + mysql/plugin_data_type.h + mysql/plugin_encryption.h + mysql/plugin_ftparser.h + mysql/plugin_function.h + mysql/plugin_password_validation.h +) +SET(PLUGIN_SERVICE_HEADERS + mysql/service_base64.h + mysql/service_log_warnings.h + mysql/service_print_check_msg.h + mysql/service_thd_autoinc.h + mysql/service_thd_wait.h + mysql/service_debug_sync.h + mysql/service_logger.h + mysql/service_progress_report.h + mysql/service_thd_error_context.h + mysql/service_wsrep.h + mysql/service_encryption_scheme.h + mysql/service_md5.h + mysql/service_sha1.h + mysql/service_thd_mdl.h + mysql/services.h + mysql/service_encryption.h + mysql/service_my_crypt.h + mysql/service_sha2.h + mysql/service_thd_rnd.h + mysql/service_json.h + mysql/service_my_print_error.h + mysql/service_sql.h + mysql/service_thd_specifics.h + mysql/service_kill_statement.h + mysql/service_my_snprintf.h + mysql/service_thd_alloc.h + mysql/service_thd_timezone.h) + +GENERATED_DOCS_PROJECT(NAME plugin_api MASK "*.h" + ${PLUGIN_API_HEADERS} ${PLUGIN_SERVICE_HEADERS}) diff --git a/include/mysql/service_debug_sync.h b/include/mysql/service_debug_sync.h index f7fdbf048324f..bdfe79b35ae26 100644 --- a/include/mysql/service_debug_sync.h +++ b/include/mysql/service_debug_sync.h @@ -223,7 +223,7 @@ There are quite a few places in MySQL, where we use a synchronization pattern like this: - +@code mysql_mutex_lock(&mutex); thd->enter_cond(&condition_variable, &mutex, new_message); #if defined(ENABLE_DEBUG_SYNC) @@ -233,7 +233,7 @@ while (!thd->killed && !end_of_wait_condition) mysql_cond_wait(&condition_variable, &mutex); thd->exit_cond(old_message); - +@endcode Here some explanations: thd->enter_cond() is used to register the condition variable and the diff --git a/include/mysql/service_logger.h b/include/mysql/service_logger.h index d11dd4291ae32..9e34c009066b1 100644 --- a/include/mysql/service_logger.h +++ b/include/mysql/service_logger.h @@ -46,7 +46,7 @@ Finally the log should be closed with logger_close(). -@notes: +@note: Implementation checks the size of the log file before it starts new printf into it. So the size of the file gets over the limit when it rotates. diff --git a/include/mysql/service_my_snprintf.h b/include/mysql/service_my_snprintf.h index 607000838327a..c91ea0ab5fd73 100644 --- a/include/mysql/service_my_snprintf.h +++ b/include/mysql/service_my_snprintf.h @@ -39,19 +39,21 @@ @note The syntax of a format string is generally the same: + @verbatim %[][][.][][] - where everything but the is optional. + @endverbatim + where everything but the \ is optional. - Two one-character are recognized: + Two one-character \ are recognized: '0' has the standard zero-padding semantics; '-' is parsed, but silently ignored; - Both and are the same as in the standard. + Both \ and \ are the same as in the standard. They can be specified as integers, or as '*' to consume an int argument. - can be 'l', 'll', or 'z'. + \ can be 'l', 'll', or 'z'. - Supported s are 's' (null pointer is accepted, printed as "(null)"), + Supported \s are 's' (null pointer is accepted, printed as "(null)"), 'c', 'd', 'i', 'u', 'x', 'X', 'o', 'p' (works as "0x%x"), 'f', and 'g'. The '$n' syntax for positional arguments is supported. @@ -60,12 +62,11 @@ Format 'sQ' quotes the string with '`' (backtick)s similar to "`%s`", - but also "escapes" existing '`'s in the string to '``' as in SQL ''''. - + but also "escapes" existing '`'s in the string to '\`\`' as in SQL ''''. Format 'sB' treats the argument as a byte sequence. It reads and prints exactly - bytes without terminating on any '\0's in the sequence. - The default when it's unspecified is not defined. + \ bytes without terminating on any '\0's in the sequence. + The default \ when it's unspecified is not defined. Format 'sT' replaces the end of the printed string with "..." if it was truncated. diff --git a/include/mysql/service_progress_report.h b/include/mysql/service_progress_report.h index 11fc24dc3b8b7..1717459f14ea3 100644 --- a/include/mysql/service_progress_report.h +++ b/include/mysql/service_progress_report.h @@ -55,6 +55,7 @@ extern struct progress_report_service_st { #else +void thd_progress_init(MYSQL_THD thd, unsigned int max_stage); /** Report progress for long running operations @@ -62,7 +63,6 @@ extern struct progress_report_service_st { @param progress Where we are now @param max_progress Progress will continue up to this */ -void thd_progress_init(MYSQL_THD thd, unsigned int max_stage); void thd_progress_report(MYSQL_THD thd, unsigned long long progress, unsigned long long max_progress); diff --git a/include/mysql/service_thd_autoinc.h b/include/mysql/service_thd_autoinc.h index 28bd2bb1a5eaf..4e881d7262ffe 100644 --- a/include/mysql/service_thd_autoinc.h +++ b/include/mysql/service_thd_autoinc.h @@ -37,9 +37,9 @@ extern struct thd_autoinc_service_st { #else /** Return autoincrement system variables - @param IN thd user thread connection handle - @param OUT off the value of @@SESSION.auto_increment_offset - @param OUT inc the value of @@SESSION.auto_increment_increment + @param[in] thd user thread connection handle + @param[out] off the value of @@SESSION.auto_increment_offset + @param[out] inc the value of @@SESSION.auto_increment_increment */ void thd_get_autoinc(const MYSQL_THD thd, unsigned long* off, unsigned long* inc); diff --git a/include/mysql/service_thd_rnd.h b/include/mysql/service_thd_rnd.h index 8761077ea7373..6d5f65227888e 100644 --- a/include/mysql/service_thd_rnd.h +++ b/include/mysql/service_thd_rnd.h @@ -46,9 +46,10 @@ double thd_rnd(MYSQL_THD thd); /** Generate string of printable random characters of requested length. - @param to[out] Buffer for generation; must be at least length+1 bytes - long; result string is always null-terminated - @param length[in] How many random characters to put in buffer + @param thd User thread connection handle + @param[out] to Buffer for generation; must be at least length+1 bytes + long; result string is always null-terminated + @param[in] length How many random characters to put in buffer */ void thd_create_random_password(MYSQL_THD thd, char *to, size_t length);