From 9214d03cf264eb73cb78fb70e8746c9897dd28b8 Mon Sep 17 00:00:00 2001 From: konakona418 Date: Fri, 16 Jan 2026 23:41:18 +0800 Subject: [PATCH 1/3] feat: format support for webui_run and webui_script --- include/webui_extras.h | 67 ++++++++++++++++++++++++++++++++++++++++++ src/webui.c | 56 +++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 include/webui_extras.h diff --git a/include/webui_extras.h b/include/webui_extras.h new file mode 100644 index 000000000..34f3bf4a9 --- /dev/null +++ b/include/webui_extras.h @@ -0,0 +1,67 @@ +/* + WebUI Library Extras + https://webui.me + https://github.com/webui-dev/webui + Copyright (c) 2020-2025 Hassan Draga. + Licensed under MIT License. + All rights reserved. + Canada. +*/ + +#ifndef _WEBUI_EXTRAS_H +#define _WEBUI_EXTRAS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "webui.h" + +/** + * @brief Construct a JavaScript string from a format string, + * then execute it without waiting for the response. All clients. + * + * @param window The window number + * @param fmt The JavaScript format string to be run + * + * @warning This function DOES NOT handle escape characters, proceed with caution. + * For example, when passing string arguments that contain quotes or backslashes, + * it may lead to unexpected behavior + * + * @note This function internally uses vsnprintf + * + * @example webui_run_fmt(myWindow, "alert('Hello %s');", "World"); + */ +WEBUI_EXPORT void webui_run_fmt(size_t window, const char* fmt, ...); + +/** + * @brief Construct a JavaScript string from a format string, + * then execute it and get the response back. Work only in single client mode. + * Make sure your local buffer can hold the response. + * + * @param window The window number + * @param timeout The execution timeout in seconds + * @param buffer The local buffer to hold the response + * @param buffer_length The local buffer size + * @param fmt The JavaScript format string to be run + * + * @return Returns True if there is no execution error + * + * @warning This function DOES NOT handle escape characters, proceed with caution. + * For example, when passing string arguments that contain quotes or backslashes, + * it may lead to unexpected behavior + * + * @note This function internally uses vsnprintf + * + * @example bool err = webui_script_fmt(myWindow, 0, myBuffer, myBufferSize, + * "return %d + %d;", 4, 6); + */ +WEBUI_EXPORT bool webui_script_fmt(size_t window, size_t timeout, + char* buffer, size_t buffer_length, + const char* fmt, ...); + +#ifdef __cplusplus +} +#endif + +#endif /*_WEBUI_EXTRAS_H */ \ No newline at end of file diff --git a/src/webui.c b/src/webui.c index 7d166404f..9b99ccf3f 100644 --- a/src/webui.c +++ b/src/webui.c @@ -847,6 +847,31 @@ void webui_run(size_t window, const char* script) { _webui_send_all(win, 0, WEBUI_CMD_JS_QUICK, script, js_len); } +void webui_run_fmt(size_t window, const char* fmt, ...) { + int len; + char* buf; + + // Precalculate actual string length + va_list args; + va_start(args, fmt); + len = vsnprintf(NULL, 0, fmt, args); + va_end(args); + + if (len < 1) return; + + buf = (char*)_webui_malloc(len + 1); + if (buf == NULL) return; + + // Format and execute + va_start(args, fmt); + vsnprintf(buf, len + 1, fmt, args); + va_end(args); + + webui_run(window, buf); + + _webui_free_mem((void*)buf); +} + void webui_set_close_handler_wv(size_t window, bool(*close_handler)(size_t window)) { // Initialization @@ -1065,6 +1090,37 @@ bool webui_script(size_t window, const char* script, size_t timeout, return webui_script_client(&e, script, timeout, buffer, buffer_length); } +bool webui_script_fmt( + size_t window, size_t timeout, + char* buffer, size_t buffer_length, + const char* fmt, ...) { + int len; + char* buf; + bool status; + + // Precalculate actual string length + va_list args; + va_start(args, fmt); + len = vsnprintf(NULL, 0, fmt, args); + va_end(args); + + if (len < 1) return false; + + buf = (char*)_webui_malloc(len + 1); + if (buf == NULL) return false; + + // Format and execute + va_start(args, fmt); + vsnprintf(buf, len + 1, fmt, args); + va_end(args); + + status = webui_script(window, buf, timeout, buffer, buffer_length); + + _webui_free_mem((void*)buf); + + return status; +} + static uint32_t _webui_generate_random_uint32() { uint32_t timestamp = (uint32_t) time(NULL); // Get the higher 16 bits From 2b155b6e9d3978d79f445eb706dcc92a9f5df5c0 Mon Sep 17 00:00:00 2001 From: konakona418 Date: Sat, 17 Jan 2026 00:52:45 +0800 Subject: [PATCH 2/3] feat: use WEBUI_EXTENSION_API to turn on/off extensions --- .../{webui_extras.h => webui_extensions.h} | 24 ++++++++++++++----- src/webui.c | 4 ++++ 2 files changed, 22 insertions(+), 6 deletions(-) rename include/{webui_extras.h => webui_extensions.h} (70%) diff --git a/include/webui_extras.h b/include/webui_extensions.h similarity index 70% rename from include/webui_extras.h rename to include/webui_extensions.h index 34f3bf4a9..48d6b4c4b 100644 --- a/include/webui_extras.h +++ b/include/webui_extensions.h @@ -8,14 +8,26 @@ Canada. */ -#ifndef _WEBUI_EXTRAS_H -#define _WEBUI_EXTRAS_H +#ifndef _WEBUI_EXTENSIONS_H +#define _WEBUI_EXTENSIONS_H #ifdef __cplusplus extern "C" { #endif -#include "webui.h" +/** + * This is to help the compiler identify whether to compile the extensions API funtions or not + * - If you are including the webui.c file to your source file directly, + * and wish to use the extensions API functions, + * please include this header file before including webui.c, + * or define this macro manually before including webui.c + * - In other cases, as long as the webui.c file is not included directly, + * you might need to define this macro in your compiler settings + */ +#define WEBUI_EXTENSIONS_API + +#include +#include /** * @brief Construct a JavaScript string from a format string, @@ -32,7 +44,7 @@ extern "C" { * * @example webui_run_fmt(myWindow, "alert('Hello %s');", "World"); */ -WEBUI_EXPORT void webui_run_fmt(size_t window, const char* fmt, ...); +void webui_run_fmt(size_t window, const char* fmt, ...); /** * @brief Construct a JavaScript string from a format string, @@ -56,7 +68,7 @@ WEBUI_EXPORT void webui_run_fmt(size_t window, const char* fmt, ...); * @example bool err = webui_script_fmt(myWindow, 0, myBuffer, myBufferSize, * "return %d + %d;", 4, 6); */ -WEBUI_EXPORT bool webui_script_fmt(size_t window, size_t timeout, +bool webui_script_fmt(size_t window, size_t timeout, char* buffer, size_t buffer_length, const char* fmt, ...); @@ -64,4 +76,4 @@ WEBUI_EXPORT bool webui_script_fmt(size_t window, size_t timeout, } #endif -#endif /*_WEBUI_EXTRAS_H */ \ No newline at end of file +#endif /*_WEBUI_EXTENSIONS_H */ \ No newline at end of file diff --git a/src/webui.c b/src/webui.c index 9b99ccf3f..271239410 100644 --- a/src/webui.c +++ b/src/webui.c @@ -847,6 +847,7 @@ void webui_run(size_t window, const char* script) { _webui_send_all(win, 0, WEBUI_CMD_JS_QUICK, script, js_len); } +#ifdef WEBUI_EXTENSION_API void webui_run_fmt(size_t window, const char* fmt, ...) { int len; char* buf; @@ -871,6 +872,7 @@ void webui_run_fmt(size_t window, const char* fmt, ...) { _webui_free_mem((void*)buf); } +#endif /* WEBUI_EXTENSION_API */ void webui_set_close_handler_wv(size_t window, bool(*close_handler)(size_t window)) { @@ -1090,6 +1092,7 @@ bool webui_script(size_t window, const char* script, size_t timeout, return webui_script_client(&e, script, timeout, buffer, buffer_length); } +#ifdef WEBUI_EXTENSION_API bool webui_script_fmt( size_t window, size_t timeout, char* buffer, size_t buffer_length, @@ -1120,6 +1123,7 @@ bool webui_script_fmt( return status; } +#endif /* WEBUI_EXTENSION_API */ static uint32_t _webui_generate_random_uint32() { uint32_t timestamp = (uint32_t) time(NULL); From bc42ffd2feb6478e644ce42313b4f0549e32ea72 Mon Sep 17 00:00:00 2001 From: konakona418 Date: Sat, 17 Jan 2026 01:21:47 +0800 Subject: [PATCH 3/3] fix: possible redefinition of macro and typo --- include/webui_extensions.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/include/webui_extensions.h b/include/webui_extensions.h index 48d6b4c4b..b6d3a7ef0 100644 --- a/include/webui_extensions.h +++ b/include/webui_extensions.h @@ -24,7 +24,14 @@ extern "C" { * - In other cases, as long as the webui.c file is not included directly, * you might need to define this macro in your compiler settings */ -#define WEBUI_EXTENSIONS_API +#ifndef WEBUI_EXTENSION_API +#define WEBUI_EXTENSION_API +#endif + +#ifndef WEBUI_EXPORT + #define WEBUI_EXPORT + #warning "WEBUI_EXPORT not defined; Please include webui.h before webui_extensions.h" +#endif #include #include @@ -44,7 +51,7 @@ extern "C" { * * @example webui_run_fmt(myWindow, "alert('Hello %s');", "World"); */ -void webui_run_fmt(size_t window, const char* fmt, ...); +WEBUI_EXPORT void webui_run_fmt(size_t window, const char* fmt, ...); /** * @brief Construct a JavaScript string from a format string, @@ -68,7 +75,7 @@ void webui_run_fmt(size_t window, const char* fmt, ...); * @example bool err = webui_script_fmt(myWindow, 0, myBuffer, myBufferSize, * "return %d + %d;", 4, 6); */ -bool webui_script_fmt(size_t window, size_t timeout, +WEBUI_EXPORT bool webui_script_fmt(size_t window, size_t timeout, char* buffer, size_t buffer_length, const char* fmt, ...);