webui-dev / webui

Use any web browser or WebView as GUI, with your preferred language in the backend and modern web technologies in the frontend, all in a lightweight portable library.
https://webui.me
MIT License
2.95k stars 171 forks source link

get_float does not work correctly #420

Closed ttytm closed 2 months ago

ttytm commented 3 months ago

Bug Description

https://github.com/webui-dev/webui/blob/9518b9e8442c9cbd275110c4e7871d0fe9f934b7/examples/C/call_c_from_js/main.c#L35

prints:

my_function_integer 4: 12345,000000

Expected Behavior

my_function_integer 4: 12345.6789

Reproduction Steps

The call_c_from_js example can be used as reproduction

Error Logs

No response

Possible Solution

No response

Version

2.5.0-beta

Environment Details (OS name, version, etc.)

Linux 6.6.33-1-lts x86_64 GNU/Linux
cc (GCC) 14.1.1 20240522
ttytm commented 3 months ago

With a fix the asserts in the added test can be enabled

https://github.com/webui-dev/webui/blob/6cefcb1f3d2f1b5f2d1573b0dc3f42fcd3ce2578/tests/call_c_from_js.c#L36-L51

hassandraga commented 3 months ago

I will look into that tomorrow, Thank you for the report @ttytm.

hassandraga commented 3 months ago

I can't reproduce the issue. Ubuntu 22.04.3 LTS Mozilla Firefox 126.0 my_function_integer 4: 12345.678900

Probably we may need the full logs to know what's going on. Also, the browser or WV you are using.

ttytm commented 3 months ago

Happens in chrome and Firefox for me.

Logs `call_c_from_js` example: ``` [User] webui_new_window() [User] webui_get_new_window_id() [Core] WebUI v2.5.0-beta.1 (GNU/Linux, GCC, Non-Encrypted) [Core] _webui_init() [Core] _webui_get_current_path() [Core] _webui_malloc([4096]) [Core] _webui_ptr_add(0x0x5c0f4c35d6b0) [Core] _webui_malloc([4096]) [Core] _webui_ptr_add(0x0x5c0f4c35f6c0) [User] webui_new_window_id([1]) [Core] _webui_malloc([2296]) [Core] _webui_ptr_add(0x0x5c0f4c361750) [Core] _webui_malloc([4096]) [Core] _webui_ptr_add(0x0x5c0f4c362760) [Core] _webui_malloc([4096]) [Core] _webui_ptr_add(0x0x5c0f4c364770) [User] webui_new_window_id() -> New window #1 @ 0x0x5c0f4c361750 [User] webui_new_window_id() -> New window Token 0x9AD7C4FE (2597831934) [User] webui_bind([1], [MyID_One], [0x0x5c0f4b48fa79]) [Core] _webui_malloc([12]) [Core] _webui_ptr_add(0x0x5c0f4c366780) [Core] _webui_get_cb_index([1/MyID_One]) [Core] _webui_set_cb_index([1/MyID_One]) [User] webui_bind([1], [MyID_Two], [0x0x5c0f4b48fae3]) [Core] _webui_malloc([12]) [Core] _webui_ptr_add(0x0x5c0f4c3667a0) [Core] _webui_get_cb_index([1/MyID_Two]) [Core] _webui_set_cb_index([1/MyID_Two]) [User] webui_bind([1], [MyID_Three], [0x0x5c0f4b48fbdf]) [Core] _webui_malloc([14]) [Core] _webui_ptr_add(0x0x5c0f4c3667c0) [Core] _webui_get_cb_index([1/MyID_Three]) [Core] _webui_set_cb_index([1/MyID_Three]) [User] webui_bind([1], [MyID_Four], [0x0x5c0f4b48fd82]) [Core] _webui_malloc([13]) [Core] _webui_ptr_add(0x0x5c0f4c3667e0) [Core] _webui_get_cb_index([1/MyID_Four]) [Core] _webui_set_cb_index([1/MyID_Four]) [User] webui_bind([1], [MyID_RawBinary], [0x0x5c0f4b48fc6b]) [Core] _webui_malloc([18]) [Core] _webui_ptr_add(0x0x5c0f4c366800) [Core] _webui_get_cb_index([1/MyID_RawBinary]) [Core] _webui_set_cb_index([1/MyID_RawBinary]) [User] webui_show([1]) [Core] _webui_show([1]) [Core] _webui_malloc([2151]) [Core] _webui_ptr_add(0x0x5c0f4c366830) [Core] _webui_is_valid_url([ Embedded HTML: - - -[HTML]- - - - - - - - - - Call C from JavaScript Example

WebUI - Call C from J p>Call C functions with arguments (See the logs in your terminal)

click="webui.call('MyID_Two', 123, 456, 789, 12345.6789);">Call my_function_integer()

Call a C function ponse

Double:
- - - - - - - - - - - - - - - - [Core] _webui_show_window(HTML, [1]) [Core] _webui_get_free_port() [Core] _webui_port_is_used([16282]) [Core] _webui_socket_test_listen_mg([16282]) [Core] _webui_malloc([64]) [Core] _webui_ptr_add(0x0x5c0f4c367840) [Core] _webui_malloc([32]) [Core] _webui_ptr_add(0x0x5c0f4c367b90) [Core] _webui_malloc([22]) [Core] _webui_ptr_add(0x0x5c0f4c3680b0) [Core] _webui_wv_show([http://localhost:16282]) [Core] _webui_wv_show() -> GTK loaded [libgtk-3.so.0] [Core] _webui_wv_show() -> WebKit loaded [libwebkit2gtk-4.1.so.0] [Core] _webui_malloc([22]) [Core] _webui_ptr_add(0x0x5c0f4c468bf0) [Core] _webui_malloc([56]) [Core] _webui_ptr_add(0x0x5c0f4c56cb80) [Core] _webui_wv_show() -> New WebView window [Core] _webui_wv_create() [Core] [Thread .] _webui_webview_thread() [Core] [Thread .] _webui_webview_thread() -> Started [Core] _webui_wv_show() -> Return [1] [Core] _webui_show_window() -> WebView Found. [Core] _webui_free_mem(0x0x5c0f4c3680b0) [Core] _webui_free_mem(0x0x5c0f4c3680b0) -> Free 32 bytes [Core] _webui_show_window() -> Waiting for window connection [Core] _webui_server_thread() [Core] _webui_server_thread([1]) -> URL: [http://localhost:16282] [Core] _webui_malloc([64]) [Core] _webui_ptr_add(0x0x713464000b70) [Core] _webui_server_thread([1]) -> Listening Success [Core] _webui_server_thread([1]) -> HTTP/WS Port: 127.0.0.1:16282 [Core] _webui_server_thread([1]) -> Timeout is 15 seconds [Core] _webui_server_thread([1]) -> Root path: . [Core] _webui_server_thread([1]) -> Waiting for first HTTP request [Core] _webui_http_handler() [Core] _webui_http_handler() -> GET [/] [Core] _webui_http_handler() -> Embedded Index HTML [Core] _webui_http_send() [Core] _webui_http_handler() -> HTTP Status Code: 200 [Core] _webui_server_thread([1]) -> Waiting for first connection [Core] _webui_http_handler() [Core] _webui_http_handler() -> GET [/webui.js] [Core] _webui_http_handler() -> WebUI-Bridge [Core] _webui_generate_js_bridge() [Core] _webui_malloc([138]) [Core] _webui_ptr_add(0x0x713458005020) [Core] _webui_malloc([21406]) [Core] _webui_ptr_add(0x0x713458006540) [Core] _webui_free_mem(0x0x713458005020) [Core] _webui_free_mem(0x0x713458005020) -> Free 256 bytes [Core] _webui_http_send() [Core] _webui_free_mem(0x0x713458006540) [Core] _webui_free_mem(0x0x713458006540) -> Free 32768 bytes [Core] _webui_http_handler() -> HTTP Status Code: 200 [Core] _webui_ws_connect_handler() [Core] _webui_ws_ready_handler() [Core] _webui_receive([1], [2], [0]) [Core] _webui_malloc([40]) [Core] _webui_ptr_add(0x0x713474004ba0) [Core] [Thread .] _webui_process_thread() [Core] _webui_process(1) [Core] _webui_process(1) -> Start [Core] _webui_process(1) -> WebSocket connected [Core] _webui_process(1) -> Finished. [Core] _webui_free_mem(0x0x71346402a5e0) [Core] _webui_free_mem(0x0x713474004ba0) [Core] _webui_free_mem(0x0x713474004ba0) -> Free 64 bytes [Loop] webui_wait() [Loop] webui_wait() -> Waiting (Timeout in 15 seconds) [Loop] webui_wait() -> Linux WebView loop [Core] _webui_server_thread([1]) -> Window Connected. [Core] _webui_wv_event_title() [Core] _webui_ws_data_handler() [Core] _webui_receive([1], [1], [49]) [Core] _webui_malloc([49]) [Core] _webui_ptr_add(0x0x713474004ba0) [Core] _webui_malloc([40]) [Core] _webui_ptr_add(0x0x713474004bf0) [Core] _webui_ws_data_handler() -> Finished. [Core] [Thread .] _webui_process_thread() [Core] _webui_process(2) [Core] _webui_process(2) -> Start [Core] _webui_get_token() [Core] _webui_get_token() -> 0x9AD7C4FE [Core] _webui_get_id() [Core] _webui_get_id() -> 0xFFFF [Core] _webui_process(2) -> Data received [Core] _webui_process(2) -> Packet Size : 49 bytes [Core] _webui_process(2) -> Packet Header : [ 0xDD 0xFE 0xC4 0xD7 0x9A 0xFF 0xFF 0xF9 ] [Core] _webui_process(2) -> Packet Token: 0x9AD7C4FE (2597831934) [Core] _webui_process(2) -> Packet ID: 0xFFFF (65535) [Core] _webui_process(2) -> Packet Data: [] [Core] _webui_process(2) -> WEBUI_CMD_CALL_FUNC [Core] _webui_process(2) -> Call ID: [65535] [Core] _webui_process(2) -> Element: [MyID_Two] [Core] _webui_generate_internal_id([1], [MyID_Two]) [Core] _webui_malloc([12]) [Core] _webui_ptr_add(0x0x71346c000bb0) [Core] _webui_malloc([288]) [Core] _webui_ptr_add(0x0x71346c000bd0) [Core] _webui_process(2) -> Argument 0: 3 bytes [Core] _webui_process(2) -> Argument 1: 3 bytes [Core] _webui_process(2) -> Argument 2: 3 bytes [Core] _webui_process(2) -> Argument 3: 10 bytes [Core] _webui_process(2) -> Expected and received 23 bytes of data. [Core] _webui_get_cb_index([1/MyID_Two]) [Core] _webui_process(2) -> Calling user callback [Call] [User] webui_get_count() my_function_integer: There is 4 arguments in this event [User] webui_get_int() [User] webui_get_int_at([0]) [User] webui_get_string_at([0]) [User] webui_get_int_at([1]) [User] webui_get_string_at([1]) [User] webui_get_int_at([2]) [User] webui_get_string_at([2]) my_function_integer 1: 123 my_function_integer 2: 456 my_function_integer 3: 789 [User] webui_get_float_at([3]) [User] webui_get_string_at([3]) my_function_integer 4: 12345,000000 [Core] _webui_process(2) -> user-callback response [] [Core] _webui_send() [Core] _webui_send() -> Token = 0x9AD7C4FE [Core] _webui_send() -> ID = 0xFFFF [Core] _webui_send() -> CMD = 0xf9 [Core] _webui_send() -> Data = 0 bytes [Core] _webui_malloc([9]) [Core] _webui_ptr_add(0x0x71346c000de0) [Core] _webui_ws_send() [Core] _webui_ws_send() -> Packet size: 9 bytes [Core] _webui_ws_send() -> Packet hex : [ 0xDD 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xF9 0x00 ] [Core] _webui_ws_send() -> 9 bytes sent. [Core] _webui_free_mem(0x0x71346c000de0) [Core] _webui_free_mem(0x0x71346c000de0) -> Free 16 bytes [Core] _webui_free_mem(0x0x5c0f4b4c20bb) [Core] _webui_free_mem(0x0x71346c000bb0) [Core] _webui_free_mem(0x0x71346c000bb0) -> Free 16 bytes [Core] _webui_free_mem(0x0x71346c000bd0) [Core] _webui_free_mem(0x0x71346c000bd0) -> Free 512 bytes [Core] _webui_process(2) -> Finished. [Core] _webui_free_mem(0x0x713474004ba0) [Core] _webui_free_mem(0x0x713474004ba0) -> Free 64 bytes [Core] _webui_free_mem(0x0x713474004bf0) [Core] _webui_free_mem(0x0x713474004bf0) -> Free 64 bytes ```

ttytm commented 3 months ago

I see it doesn't reproduces in CI (asserts for floats are currently commented out, values are only printed):

JS passed:

await webui.assert_float(1.0, 2.3, 3.45);

backed prints:

num1: 1.000000, num2: 2.300000, num3: 3.450000

ref. Test Static step in: webui-dev/webui/actions/runs/9541169685/job/26293993613

Looks correct on the ubuntu runner.

ttytm commented 3 months ago

The get_string call doesn't look right:

[User] webui_get_float_at([3])
[User] webui_get_string_at([3])

The example is unchanged ofc.

hassandraga commented 3 months ago
[Core]          _webui_process(2) -> Argument 0: 3 bytes
[Core]          _webui_process(2) -> Argument 1: 3 bytes
[Core]          _webui_process(2) -> Argument 2: 3 bytes
[Core]          _webui_process(2) -> Argument 3: 10 bytes
[Core]          _webui_process(2) -> Expected and received 23 bytes of data.

Looks correct, the UI (bridge) sent all data. Can you please try:

assert(num3 == 3.45f);
ttytm commented 3 months ago
[Core]          _webui_process(2) -> Argument 0: 3 bytes
[Core]          _webui_process(2) -> Argument 1: 3 bytes
[Core]          _webui_process(2) -> Argument 2: 3 bytes
[Core]          _webui_process(2) -> Argument 3: 10 bytes
[Core]          _webui_process(2) -> Expected and received 23 bytes of data.

Looks correct, the UI (bridge) sent all data. Can you please try:

assert(num3 == 3.45f);

I'm receiving a 00 decimal so in the test its 3.00 and the assert does not work.

As the logs show, my_function_integer 4: 12345,000000 when 12345.6789 was passed.

hassandraga commented 3 months ago

Yes, I want to make sure that the actual value is .0, I want to be sure the issue is not with the print format.

ttytm commented 3 months ago

Yep the check failed, tested with atof/strtod/sscanf. The conversion works correctly when setlocale(LC_NUMERIC, "C"); is set.

Then the assert works with the fully specified number:

assert(num3 == 3.450000); // true (requires setlocal on the tested machine)
assert(num3 == 3.45f); // false
hassandraga commented 2 months ago

I tried to reproduce the issue, but I can't, it always works fine for me. I manually test it in:

hassandraga commented 2 months ago

Please re-open if the issue still exists.