gemba 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. checksums.yaml +4 -4
  2. data/THIRD_PARTY_NOTICES +37 -2
  3. data/assets/placeholder_boxart.png +0 -0
  4. data/bin/gemba +2 -2
  5. data/ext/gemba/extconf.rb +23 -1
  6. data/ext/gemba/gemba_ext.c +436 -2
  7. data/ext/gemba/gemba_ext.h +2 -0
  8. data/gemba.gemspec +5 -3
  9. data/lib/gemba/achievements/achievement.rb +23 -0
  10. data/lib/gemba/achievements/backend.rb +186 -0
  11. data/lib/gemba/achievements/cache.rb +70 -0
  12. data/lib/gemba/achievements/credentials_presenter.rb +142 -0
  13. data/lib/gemba/achievements/fake_backend.rb +205 -0
  14. data/lib/gemba/achievements/null_backend.rb +11 -0
  15. data/lib/gemba/achievements/offline_backend.rb +168 -0
  16. data/lib/gemba/achievements/retro_achievements/backend.rb +453 -0
  17. data/lib/gemba/achievements/retro_achievements/cli_sync_requester.rb +64 -0
  18. data/lib/gemba/achievements/retro_achievements/ping_worker.rb +27 -0
  19. data/lib/gemba/achievements.rb +19 -0
  20. data/lib/gemba/achievements_window.rb +556 -0
  21. data/lib/gemba/app_controller.rb +1015 -0
  22. data/lib/gemba/bios.rb +54 -0
  23. data/lib/gemba/boxart_fetcher/libretro_backend.rb +39 -0
  24. data/lib/gemba/boxart_fetcher/null_backend.rb +12 -0
  25. data/lib/gemba/boxart_fetcher.rb +79 -0
  26. data/lib/gemba/bus_emitter.rb +13 -0
  27. data/lib/gemba/child_window.rb +24 -1
  28. data/lib/gemba/cli/commands/config_cmd.rb +83 -0
  29. data/lib/gemba/cli/commands/decode.rb +154 -0
  30. data/lib/gemba/cli/commands/patch.rb +78 -0
  31. data/lib/gemba/cli/commands/play.rb +78 -0
  32. data/lib/gemba/cli/commands/record.rb +114 -0
  33. data/lib/gemba/cli/commands/replay.rb +161 -0
  34. data/lib/gemba/cli/commands/retro_achievements.rb +213 -0
  35. data/lib/gemba/cli/commands/version.rb +22 -0
  36. data/lib/gemba/cli.rb +52 -364
  37. data/lib/gemba/config.rb +134 -1
  38. data/lib/gemba/data/gb_games.json +1 -0
  39. data/lib/gemba/data/gb_md5.json +1 -0
  40. data/lib/gemba/data/gba_games.json +1 -0
  41. data/lib/gemba/data/gba_md5.json +1 -0
  42. data/lib/gemba/data/gbc_games.json +1 -0
  43. data/lib/gemba/data/gbc_md5.json +1 -0
  44. data/lib/gemba/emulator_frame.rb +1060 -0
  45. data/lib/gemba/event_bus.rb +48 -0
  46. data/lib/gemba/frame_stack.rb +60 -0
  47. data/lib/gemba/game_index.rb +84 -0
  48. data/lib/gemba/game_picker_frame.rb +268 -0
  49. data/lib/gemba/gamepad_map.rb +103 -0
  50. data/lib/gemba/headless.rb +6 -5
  51. data/lib/gemba/headless_player.rb +33 -3
  52. data/lib/gemba/help_window.rb +61 -0
  53. data/lib/gemba/hotkey_map.rb +3 -1
  54. data/lib/gemba/input_recorder.rb +107 -0
  55. data/lib/gemba/input_replayer.rb +119 -0
  56. data/lib/gemba/keyboard_map.rb +90 -0
  57. data/lib/gemba/locales/en.yml +97 -5
  58. data/lib/gemba/locales/ja.yml +97 -5
  59. data/lib/gemba/main_window.rb +56 -0
  60. data/lib/gemba/modal_stack.rb +81 -0
  61. data/lib/gemba/patcher_window.rb +223 -0
  62. data/lib/gemba/platform/gb.rb +21 -0
  63. data/lib/gemba/platform/gba.rb +21 -0
  64. data/lib/gemba/platform/gbc.rb +23 -0
  65. data/lib/gemba/platform.rb +20 -0
  66. data/lib/gemba/platform_open.rb +19 -0
  67. data/lib/gemba/recorder.rb +4 -3
  68. data/lib/gemba/replay_player.rb +691 -0
  69. data/lib/gemba/rom_info.rb +57 -0
  70. data/lib/gemba/rom_info_window.rb +16 -3
  71. data/lib/gemba/rom_library.rb +106 -0
  72. data/lib/gemba/rom_overrides.rb +47 -0
  73. data/lib/gemba/rom_patcher/bps.rb +161 -0
  74. data/lib/gemba/rom_patcher/ips.rb +101 -0
  75. data/lib/gemba/rom_patcher/ups.rb +118 -0
  76. data/lib/gemba/rom_patcher.rb +109 -0
  77. data/lib/gemba/{rom_loader.rb → rom_resolver.rb} +7 -6
  78. data/lib/gemba/runtime.rb +59 -26
  79. data/lib/gemba/save_state_manager.rb +4 -7
  80. data/lib/gemba/save_state_picker.rb +17 -4
  81. data/lib/gemba/session_logger.rb +64 -0
  82. data/lib/gemba/settings/audio_tab.rb +77 -0
  83. data/lib/gemba/settings/gamepad_tab.rb +351 -0
  84. data/lib/gemba/settings/hotkeys_tab.rb +259 -0
  85. data/lib/gemba/settings/paths.rb +11 -0
  86. data/lib/gemba/settings/recording_tab.rb +83 -0
  87. data/lib/gemba/settings/save_states_tab.rb +91 -0
  88. data/lib/gemba/settings/system_tab.rb +362 -0
  89. data/lib/gemba/settings/video_tab.rb +318 -0
  90. data/lib/gemba/settings_window.rb +162 -1036
  91. data/lib/gemba/version.rb +1 -1
  92. data/lib/gemba/virtual_keyboard.rb +19 -0
  93. data/lib/gemba.rb +2 -12
  94. data/test/achievements_window/test_bulk_sync.rb +218 -0
  95. data/test/achievements_window/test_bus_events.rb +125 -0
  96. data/test/achievements_window/test_close_confirmation.rb +201 -0
  97. data/test/achievements_window/test_initial_state.rb +164 -0
  98. data/test/achievements_window/test_sorting.rb +227 -0
  99. data/test/achievements_window/test_tree_rendering.rb +133 -0
  100. data/test/fixtures/fake_bios.bin +0 -0
  101. data/test/fixtures/pong.gba +0 -0
  102. data/test/fixtures/test.gb +0 -0
  103. data/test/fixtures/test.gbc +0 -0
  104. data/test/fixtures/test_quicksave.ss +0 -0
  105. data/test/screenshots/no_focus.png +0 -0
  106. data/test/shared/teek_test_worker.rb +17 -1
  107. data/test/shared/tk_test_helper.rb +91 -4
  108. data/test/support/achievements_window_helpers.rb +18 -0
  109. data/test/support/fake_core.rb +25 -0
  110. data/test/support/fake_ra_runtime.rb +74 -0
  111. data/test/support/fake_requester.rb +68 -0
  112. data/test/support/player_helpers.rb +20 -5
  113. data/test/test_achievement.rb +32 -0
  114. data/test/{test_player.rb → test_app_controller.rb} +353 -85
  115. data/test/test_bios.rb +123 -0
  116. data/test/test_boxart_fetcher.rb +150 -0
  117. data/test/test_cli.rb +17 -265
  118. data/test/test_cli_config.rb +64 -0
  119. data/test/test_cli_decode.rb +97 -0
  120. data/test/test_cli_patch.rb +58 -0
  121. data/test/test_cli_play.rb +213 -0
  122. data/test/test_cli_ra.rb +175 -0
  123. data/test/test_cli_record.rb +69 -0
  124. data/test/test_cli_replay.rb +72 -0
  125. data/test/test_cli_sync_requester.rb +152 -0
  126. data/test/test_cli_version.rb +27 -0
  127. data/test/test_config.rb +2 -3
  128. data/test/test_config_ra.rb +69 -0
  129. data/test/test_core.rb +62 -1
  130. data/test/test_credentials_presenter.rb +192 -0
  131. data/test/test_event_bus.rb +100 -0
  132. data/test/test_fake_backend_achievements.rb +130 -0
  133. data/test/test_fake_backend_auth.rb +68 -0
  134. data/test/test_game_index.rb +77 -0
  135. data/test/test_game_picker_frame.rb +310 -0
  136. data/test/test_gamepad_map.rb +1 -3
  137. data/test/test_headless_player.rb +17 -3
  138. data/test/test_help_window.rb +82 -0
  139. data/test/test_hotkey_map.rb +22 -1
  140. data/test/test_input_recorder.rb +179 -0
  141. data/test/test_input_replay_determinism.rb +113 -0
  142. data/test/test_input_replayer.rb +162 -0
  143. data/test/test_keyboard_map.rb +1 -3
  144. data/test/test_libretro_backend.rb +41 -0
  145. data/test/test_locale.rb +1 -1
  146. data/test/test_logging.rb +123 -0
  147. data/test/test_null_backend.rb +42 -0
  148. data/test/test_offline_backend.rb +116 -0
  149. data/test/test_overlay_renderer.rb +1 -1
  150. data/test/test_platform.rb +149 -0
  151. data/test/test_ra_backend.rb +313 -0
  152. data/test/test_ra_backend_unlock_gate.rb +56 -0
  153. data/test/test_recorder.rb +0 -3
  154. data/test/test_replay_player.rb +316 -0
  155. data/test/test_rom_info.rb +149 -0
  156. data/test/test_rom_overrides.rb +86 -0
  157. data/test/test_rom_patcher.rb +382 -0
  158. data/test/{test_rom_loader.rb → test_rom_resolver.rb} +25 -26
  159. data/test/test_save_state_manager.rb +2 -4
  160. data/test/test_settings_audio.rb +107 -0
  161. data/test/test_settings_hotkeys.rb +83 -66
  162. data/test/test_settings_recording.rb +49 -0
  163. data/test/test_settings_save_states.rb +97 -0
  164. data/test/test_settings_system.rb +133 -0
  165. data/test/test_settings_video.rb +450 -0
  166. data/test/test_settings_window.rb +76 -507
  167. data/test/test_tip_service.rb +6 -6
  168. data/test/test_toast_overlay.rb +1 -1
  169. data/test/test_virtual_events.rb +156 -0
  170. data/test/test_virtual_keyboard.rb +1 -1
  171. data/vendor/rcheevos/CHANGELOG.md +495 -0
  172. data/vendor/rcheevos/LICENSE +21 -0
  173. data/vendor/rcheevos/Package.swift +33 -0
  174. data/vendor/rcheevos/README.md +67 -0
  175. data/vendor/rcheevos/include/module.modulemap +70 -0
  176. data/vendor/rcheevos/include/rc_api_editor.h +296 -0
  177. data/vendor/rcheevos/include/rc_api_info.h +280 -0
  178. data/vendor/rcheevos/include/rc_api_request.h +77 -0
  179. data/vendor/rcheevos/include/rc_api_runtime.h +417 -0
  180. data/vendor/rcheevos/include/rc_api_user.h +262 -0
  181. data/vendor/rcheevos/include/rc_client.h +877 -0
  182. data/vendor/rcheevos/include/rc_client_raintegration.h +101 -0
  183. data/vendor/rcheevos/include/rc_consoles.h +138 -0
  184. data/vendor/rcheevos/include/rc_error.h +59 -0
  185. data/vendor/rcheevos/include/rc_export.h +100 -0
  186. data/vendor/rcheevos/include/rc_hash.h +200 -0
  187. data/vendor/rcheevos/include/rc_runtime.h +148 -0
  188. data/vendor/rcheevos/include/rc_runtime_types.h +452 -0
  189. data/vendor/rcheevos/include/rc_util.h +51 -0
  190. data/vendor/rcheevos/include/rcheevos.h +8 -0
  191. data/vendor/rcheevos/src/rapi/rc_api_common.c +1379 -0
  192. data/vendor/rcheevos/src/rapi/rc_api_common.h +88 -0
  193. data/vendor/rcheevos/src/rapi/rc_api_editor.c +625 -0
  194. data/vendor/rcheevos/src/rapi/rc_api_info.c +587 -0
  195. data/vendor/rcheevos/src/rapi/rc_api_runtime.c +901 -0
  196. data/vendor/rcheevos/src/rapi/rc_api_user.c +483 -0
  197. data/vendor/rcheevos/src/rc_client.c +6941 -0
  198. data/vendor/rcheevos/src/rc_client_external.c +281 -0
  199. data/vendor/rcheevos/src/rc_client_external.h +177 -0
  200. data/vendor/rcheevos/src/rc_client_external_versions.h +171 -0
  201. data/vendor/rcheevos/src/rc_client_internal.h +409 -0
  202. data/vendor/rcheevos/src/rc_client_raintegration.c +566 -0
  203. data/vendor/rcheevos/src/rc_client_raintegration_internal.h +61 -0
  204. data/vendor/rcheevos/src/rc_client_types.natvis +396 -0
  205. data/vendor/rcheevos/src/rc_compat.c +251 -0
  206. data/vendor/rcheevos/src/rc_compat.h +121 -0
  207. data/vendor/rcheevos/src/rc_libretro.c +915 -0
  208. data/vendor/rcheevos/src/rc_libretro.h +98 -0
  209. data/vendor/rcheevos/src/rc_util.c +199 -0
  210. data/vendor/rcheevos/src/rc_version.c +11 -0
  211. data/vendor/rcheevos/src/rc_version.h +32 -0
  212. data/vendor/rcheevos/src/rcheevos/alloc.c +312 -0
  213. data/vendor/rcheevos/src/rcheevos/condition.c +754 -0
  214. data/vendor/rcheevos/src/rcheevos/condset.c +777 -0
  215. data/vendor/rcheevos/src/rcheevos/consoleinfo.c +1215 -0
  216. data/vendor/rcheevos/src/rcheevos/format.c +330 -0
  217. data/vendor/rcheevos/src/rcheevos/lboard.c +287 -0
  218. data/vendor/rcheevos/src/rcheevos/memref.c +805 -0
  219. data/vendor/rcheevos/src/rcheevos/operand.c +607 -0
  220. data/vendor/rcheevos/src/rcheevos/rc_internal.h +390 -0
  221. data/vendor/rcheevos/src/rcheevos/rc_runtime_types.natvis +541 -0
  222. data/vendor/rcheevos/src/rcheevos/rc_validate.c +1406 -0
  223. data/vendor/rcheevos/src/rcheevos/rc_validate.h +18 -0
  224. data/vendor/rcheevos/src/rcheevos/richpresence.c +922 -0
  225. data/vendor/rcheevos/src/rcheevos/runtime.c +852 -0
  226. data/vendor/rcheevos/src/rcheevos/runtime_progress.c +1073 -0
  227. data/vendor/rcheevos/src/rcheevos/trigger.c +344 -0
  228. data/vendor/rcheevos/src/rcheevos/value.c +935 -0
  229. data/vendor/rcheevos/src/rhash/aes.c +480 -0
  230. data/vendor/rcheevos/src/rhash/aes.h +49 -0
  231. data/vendor/rcheevos/src/rhash/cdreader.c +838 -0
  232. data/vendor/rcheevos/src/rhash/hash.c +1402 -0
  233. data/vendor/rcheevos/src/rhash/hash_disc.c +1340 -0
  234. data/vendor/rcheevos/src/rhash/hash_encrypted.c +566 -0
  235. data/vendor/rcheevos/src/rhash/hash_rom.c +426 -0
  236. data/vendor/rcheevos/src/rhash/hash_zip.c +460 -0
  237. data/vendor/rcheevos/src/rhash/md5.c +382 -0
  238. data/vendor/rcheevos/src/rhash/md5.h +91 -0
  239. data/vendor/rcheevos/src/rhash/rc_hash_internal.h +116 -0
  240. data/vendor/rcheevos/test/libretro.h +205 -0
  241. data/vendor/rcheevos/test/rapi/test_rc_api_common.c +941 -0
  242. data/vendor/rcheevos/test/rapi/test_rc_api_editor.c +931 -0
  243. data/vendor/rcheevos/test/rapi/test_rc_api_info.c +545 -0
  244. data/vendor/rcheevos/test/rapi/test_rc_api_runtime.c +2213 -0
  245. data/vendor/rcheevos/test/rapi/test_rc_api_user.c +998 -0
  246. data/vendor/rcheevos/test/rcheevos/mock_memory.h +32 -0
  247. data/vendor/rcheevos/test/rcheevos/test_condition.c +570 -0
  248. data/vendor/rcheevos/test/rcheevos/test_condset.c +5170 -0
  249. data/vendor/rcheevos/test/rcheevos/test_consoleinfo.c +203 -0
  250. data/vendor/rcheevos/test/rcheevos/test_format.c +112 -0
  251. data/vendor/rcheevos/test/rcheevos/test_lboard.c +746 -0
  252. data/vendor/rcheevos/test/rcheevos/test_memref.c +520 -0
  253. data/vendor/rcheevos/test/rcheevos/test_operand.c +692 -0
  254. data/vendor/rcheevos/test/rcheevos/test_rc_validate.c +502 -0
  255. data/vendor/rcheevos/test/rcheevos/test_richpresence.c +1564 -0
  256. data/vendor/rcheevos/test/rcheevos/test_runtime.c +1667 -0
  257. data/vendor/rcheevos/test/rcheevos/test_runtime_progress.c +1821 -0
  258. data/vendor/rcheevos/test/rcheevos/test_timing.c +166 -0
  259. data/vendor/rcheevos/test/rcheevos/test_trigger.c +2521 -0
  260. data/vendor/rcheevos/test/rcheevos/test_value.c +870 -0
  261. data/vendor/rcheevos/test/rcheevos-test.sln +46 -0
  262. data/vendor/rcheevos/test/rcheevos-test.vcxproj +239 -0
  263. data/vendor/rcheevos/test/rcheevos-test.vcxproj.filters +335 -0
  264. data/vendor/rcheevos/test/rhash/data.c +657 -0
  265. data/vendor/rcheevos/test/rhash/data.h +32 -0
  266. data/vendor/rcheevos/test/rhash/mock_filereader.c +236 -0
  267. data/vendor/rcheevos/test/rhash/mock_filereader.h +31 -0
  268. data/vendor/rcheevos/test/rhash/test_cdreader.c +920 -0
  269. data/vendor/rcheevos/test/rhash/test_hash.c +310 -0
  270. data/vendor/rcheevos/test/rhash/test_hash_disc.c +1450 -0
  271. data/vendor/rcheevos/test/rhash/test_hash_rom.c +899 -0
  272. data/vendor/rcheevos/test/rhash/test_hash_zip.c +551 -0
  273. data/vendor/rcheevos/test/test.c +113 -0
  274. data/vendor/rcheevos/test/test_framework.h +205 -0
  275. data/vendor/rcheevos/test/test_rc_client.c +10509 -0
  276. data/vendor/rcheevos/test/test_rc_client_external.c +2197 -0
  277. data/vendor/rcheevos/test/test_rc_client_raintegration.c +441 -0
  278. data/vendor/rcheevos/test/test_rc_libretro.c +952 -0
  279. data/vendor/rcheevos/test/test_types.natvis +9 -0
  280. data/vendor/rcheevos/validator/validator.c +658 -0
  281. data/vendor/rcheevos/validator/validator.vcxproj +152 -0
  282. data/vendor/rcheevos/validator/validator.vcxproj.filters +82 -0
  283. metadata +274 -11
  284. data/lib/gemba/input_mappings.rb +0 -214
  285. data/lib/gemba/player.rb +0 -1525
@@ -0,0 +1,870 @@
1
+ #include "rc_internal.h"
2
+
3
+ #include "../test_framework.h"
4
+ #include "mock_memory.h"
5
+
6
+ static void test_evaluate_value(const char* memaddr, int expected_value) {
7
+ rc_value_t* self;
8
+ /* bytes 5-8 are the float value for pi */
9
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56, 0xDB, 0x0F, 0x49, 0x40};
10
+ memory_t memory;
11
+ char buffer[2048];
12
+ unsigned* overflow;
13
+ int ret;
14
+
15
+ memory.ram = ram;
16
+ memory.size = sizeof(ram);
17
+
18
+ ret = rc_value_size(memaddr);
19
+ ASSERT_NUM_GREATER_EQUALS(ret, 0);
20
+
21
+ overflow = (unsigned*)(((char*)buffer) + ret);
22
+ *overflow = 0xCDCDCDCD;
23
+
24
+ self = rc_parse_value(buffer, memaddr, NULL, 0);
25
+ ASSERT_PTR_NOT_NULL(self);
26
+ if (*overflow != 0xCDCDCDCD) {
27
+ ASSERT_FAIL("write past end of buffer");
28
+ }
29
+
30
+ ret = rc_evaluate_value(self, peek, &memory, NULL);
31
+ ASSERT_NUM_EQUALS(ret, expected_value);
32
+ }
33
+
34
+ static void test_invalid_value(const char* memaddr, int expected_error) {
35
+ int ret = rc_value_size(memaddr);
36
+ ASSERT_NUM_EQUALS(ret, expected_error);
37
+ }
38
+
39
+ static void test_measured_value_target(const char* memaddr, int expected_target) {
40
+ rc_value_t* self;
41
+ char buffer[2048];
42
+ unsigned* overflow;
43
+ int ret;
44
+
45
+ ret = rc_value_size(memaddr);
46
+ ASSERT_NUM_GREATER_EQUALS(ret, 0);
47
+
48
+ overflow = (unsigned*)(((char*)buffer) + ret);
49
+ *overflow = 0xCDCDCDCD;
50
+
51
+ self = rc_parse_value(buffer, memaddr, NULL, 0);
52
+ ASSERT_PTR_NOT_NULL(self);
53
+ if (*overflow != 0xCDCDCDCD) {
54
+ ASSERT_FAIL("write past end of buffer");
55
+ }
56
+
57
+ ASSERT_NUM_EQUALS(self->conditions->conditions->required_hits, expected_target);
58
+ }
59
+
60
+ static void test_evaluate_measured_value_with_pause() {
61
+ rc_value_t* self;
62
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
63
+ memory_t memory;
64
+ char buffer[2048];
65
+ const char* memaddr = "P:0xH0003=hAB_M:0xH0002!=d0xH0002";
66
+ int ret;
67
+
68
+ memory.ram = ram;
69
+ memory.size = sizeof(ram);
70
+
71
+ ret = rc_value_size(memaddr);
72
+ ASSERT_NUM_GREATER_EQUALS(ret, 0);
73
+
74
+ self = rc_parse_value(buffer, memaddr, NULL, 0);
75
+ ASSERT_PTR_NOT_NULL(self);
76
+
77
+ /* should initially be paused, no hits captured */
78
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
79
+
80
+ /* pause should prevent hitcount */
81
+ ram[2]++;
82
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
83
+
84
+ /* unpause should not report the change that occurred while paused */
85
+ ram[3] = 0;
86
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
87
+
88
+ /* hitcount should be captured */
89
+ ram[2]++;
90
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 1);
91
+
92
+ /* pause should return current hitcount */
93
+ ram[3] = 0xAB;
94
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 1);
95
+
96
+ /* pause should prevent hitcount */
97
+ ram[2]++;
98
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 1);
99
+
100
+ /* unpause should not report the change that occurred while paused */
101
+ ram[3] = 0;
102
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 1);
103
+
104
+ /* additional hitcount should be captured */
105
+ ram[2]++;
106
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 2);
107
+ }
108
+
109
+ static void test_evaluated_and_next_measured_if_value() {
110
+ rc_value_t* self;
111
+ const rc_condition_t* cond2;
112
+ const rc_condition_t* cond4;
113
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
114
+ memory_t memory;
115
+ char buffer[2048];
116
+ const char* memaddr = "R:0xH0004=1_N:0xH0000=1.1._N:d0xH0000=9_Q:0xH0000=0.1._M:100";
117
+ int ret;
118
+
119
+ memory.ram = ram;
120
+ memory.size = sizeof(ram);
121
+
122
+ ret = rc_value_size(memaddr);
123
+ ASSERT_NUM_GREATER_EQUALS(ret, 0);
124
+
125
+ self = rc_parse_value(buffer, memaddr, NULL, 0);
126
+ ASSERT_PTR_NOT_NULL(self);
127
+
128
+ cond2 = self->conditions->conditions->next;
129
+ cond4 = cond2->next->next;
130
+
131
+ /* measured if cannot be true */
132
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
133
+ ASSERT_NUM_EQUALS(cond2->current_hits, 0);
134
+ ASSERT_NUM_EQUALS(cond4->current_hits, 0);
135
+
136
+ /* capture first hit, measured_if still not true */
137
+ ram[0] = 1;
138
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
139
+ ASSERT_NUM_EQUALS(cond2->current_hits, 1);
140
+ ASSERT_NUM_EQUALS(cond4->current_hits, 0);
141
+
142
+ /* reset */
143
+ ram[4] = 1;
144
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
145
+ ASSERT_NUM_EQUALS(cond2->current_hits, 0);
146
+ ASSERT_NUM_EQUALS(cond4->current_hits, 0);
147
+
148
+ /* clear reset */
149
+ ram[4] = 0;
150
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
151
+ ASSERT_NUM_EQUALS(cond2->current_hits, 1);
152
+ ASSERT_NUM_EQUALS(cond4->current_hits, 0);
153
+
154
+ /* prime measured_if */
155
+ ram[0] = 9;
156
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
157
+ ASSERT_NUM_EQUALS(cond2->current_hits, 1);
158
+ ASSERT_NUM_EQUALS(cond4->current_hits, 0);
159
+
160
+ /* trigger measured if */
161
+ ram[0] = 0;
162
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 100);
163
+ ASSERT_NUM_EQUALS(cond2->current_hits, 1);
164
+ ASSERT_NUM_EQUALS(cond4->current_hits, 1);
165
+
166
+ /* measured if should remain triggered */
167
+ ram[0] = 1;
168
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 100);
169
+ ASSERT_NUM_EQUALS(cond2->current_hits, 1);
170
+ ASSERT_NUM_EQUALS(cond4->current_hits, 1);
171
+
172
+ /* reset */
173
+ ram[4] = 1;
174
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
175
+ ASSERT_NUM_EQUALS(cond2->current_hits, 0);
176
+ ASSERT_NUM_EQUALS(cond4->current_hits, 0);
177
+ }
178
+
179
+ static void test_evaluate_measured_value_with_reset() {
180
+ rc_value_t* self;
181
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
182
+ memory_t memory;
183
+ char buffer[2048];
184
+ const char* memaddr = "R:0xH0003=hAB_M:0xH0002!=d0xH0002";
185
+ int ret;
186
+
187
+ memory.ram = ram;
188
+ memory.size = sizeof(ram);
189
+
190
+ ret = rc_value_size(memaddr);
191
+ ASSERT_NUM_GREATER_EQUALS(ret, 0);
192
+
193
+ self = rc_parse_value(buffer, memaddr, NULL, 0);
194
+ ASSERT_PTR_NOT_NULL(self);
195
+
196
+ /* reset should initially be true, no hits captured */
197
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
198
+
199
+ /* reset should prevent hitcount */
200
+ ram[2]++;
201
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
202
+
203
+ /* reset no longer true, change while reset shouldn't be captured */
204
+ ram[3] = 0;
205
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
206
+
207
+ /* additional hitcount should be captured */
208
+ ram[2]++;
209
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 1);
210
+
211
+ /* reset should clear hit count */
212
+ ram[3] = 0xAB;
213
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
214
+
215
+ /* reset should prevent hitcount */
216
+ ram[2]++;
217
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
218
+
219
+ /* reset no longer true, change while reset shouldn't be captured */
220
+ ram[3] = 0;
221
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
222
+
223
+ /* additional hitcount should be captured */
224
+ ram[2]++;
225
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 1);
226
+ }
227
+
228
+ static void init_typed_value(rc_typed_value_t* value, uint8_t type, uint32_t u32, double f32) {
229
+ value->type = type;
230
+
231
+ switch (type) {
232
+ case RC_VALUE_TYPE_UNSIGNED:
233
+ value->value.u32 = u32;
234
+ break;
235
+
236
+ case RC_VALUE_TYPE_SIGNED:
237
+ value->value.i32 = (int)u32;
238
+ break;
239
+
240
+ case RC_VALUE_TYPE_FLOAT:
241
+ value->value.f32 = (float)f32;
242
+ break;
243
+
244
+ case RC_VALUE_TYPE_NONE:
245
+ value->value.u32 = 0xCDCDCDCD; /* force uninitialized value */
246
+ break;
247
+
248
+ default:
249
+ break;
250
+ }
251
+ }
252
+
253
+ static void _assert_typed_value(const rc_typed_value_t* value, uint8_t type, uint32_t u32, double f32) {
254
+ ASSERT_NUM_EQUALS(value->type, type);
255
+
256
+ switch (type) {
257
+ case RC_VALUE_TYPE_UNSIGNED:
258
+ ASSERT_NUM_EQUALS(value->value.u32, u32);
259
+ break;
260
+
261
+ case RC_VALUE_TYPE_SIGNED:
262
+ ASSERT_NUM_EQUALS(value->value.i32, (int)u32);
263
+ break;
264
+
265
+ case RC_VALUE_TYPE_FLOAT:
266
+ ASSERT_FLOAT_EQUALS(value->value.f32, (float)f32);
267
+ break;
268
+
269
+ default:
270
+ break;
271
+ }
272
+ }
273
+ #define assert_typed_value(value, type, u32, f32) ASSERT_HELPER(_assert_typed_value(value, type, u32, f32), "assert_typed_value")
274
+
275
+ static void test_typed_value_convert(uint8_t type, uint32_t u32, double f32, uint8_t new_type, uint32_t new_u32, double new_f32) {
276
+ rc_typed_value_t value;
277
+ init_typed_value(&value, type, u32, f32);
278
+
279
+ rc_typed_value_convert(&value, new_type);
280
+
281
+ assert_typed_value(&value, new_type, new_u32, new_f32);
282
+ }
283
+
284
+ static void test_typed_value_conversion() {
285
+ /* unsigned source */
286
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_UNSIGNED, 0, 0.0, RC_VALUE_TYPE_UNSIGNED, 0, 0.0);
287
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_UNSIGNED, 12, 0.0, RC_VALUE_TYPE_UNSIGNED, 12, 0.0);
288
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFF, 0.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFF, 0.0);
289
+
290
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_UNSIGNED, 0, 0.0, RC_VALUE_TYPE_SIGNED, 0, 0.0);
291
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_UNSIGNED, 12, 0.0, RC_VALUE_TYPE_SIGNED, 12, 0.0);
292
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFF, 0.0, RC_VALUE_TYPE_SIGNED, (unsigned)-1, 0.0);
293
+
294
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_UNSIGNED, 0, 0.0, RC_VALUE_TYPE_FLOAT, 0, 0.0);
295
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_UNSIGNED, 12, 0.0, RC_VALUE_TYPE_FLOAT, 0, 12.0);
296
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFF, 0.0, RC_VALUE_TYPE_FLOAT, 0, 4294967295.0);
297
+
298
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_UNSIGNED, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
299
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_UNSIGNED, 12, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
300
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFF, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
301
+
302
+ /* signed source */
303
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_SIGNED, 0, 0.0, RC_VALUE_TYPE_UNSIGNED, 0, 0.0);
304
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_SIGNED, 12, 0.0, RC_VALUE_TYPE_UNSIGNED, 12, 0.0);
305
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_SIGNED, (unsigned)-1, 0.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFF, 0.0);
306
+
307
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_SIGNED, 0, 0.0, RC_VALUE_TYPE_SIGNED, 0, 0.0);
308
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_SIGNED, 12, 0.0, RC_VALUE_TYPE_SIGNED, 12, 0.0);
309
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_SIGNED, (unsigned)-1, 0.0, RC_VALUE_TYPE_SIGNED, (unsigned)-1, 0.0);
310
+
311
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_SIGNED, 0, 0.0, RC_VALUE_TYPE_FLOAT, 0, 0.0);
312
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_SIGNED, 12, 0.0, RC_VALUE_TYPE_FLOAT, 0, 12.0);
313
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_SIGNED, (unsigned)-1, 0.0, RC_VALUE_TYPE_FLOAT, 0, -1.0);
314
+
315
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_SIGNED, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
316
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_SIGNED, 12, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
317
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_SIGNED, (unsigned)-1, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
318
+
319
+ /* float source (whole numbers) */
320
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, 0.0, RC_VALUE_TYPE_UNSIGNED, 0, 0.0);
321
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, 12.0, RC_VALUE_TYPE_UNSIGNED, 12, 0.0);
322
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, -1.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFF, 0.0);
323
+
324
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, 0.0, RC_VALUE_TYPE_SIGNED, 0, 0.0);
325
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, 12.0, RC_VALUE_TYPE_SIGNED, 12, 0.0);
326
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, -1.0, RC_VALUE_TYPE_SIGNED, (unsigned)-1, 0.0);
327
+
328
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, 0.0, RC_VALUE_TYPE_FLOAT, 0, 0.0);
329
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, 12.0, RC_VALUE_TYPE_FLOAT, 0, 12.0);
330
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, -1.0, RC_VALUE_TYPE_FLOAT, 0, -1.0);
331
+
332
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
333
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, 12.0, RC_VALUE_TYPE_NONE, 0, 0.0);
334
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, -1.0, RC_VALUE_TYPE_NONE, 0, 0.0);
335
+
336
+ /* float source (non-whole numbers) */
337
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_FLOAT, 0, 3.14159);
338
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_UNSIGNED, 3, 0);
339
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_SIGNED, 3, 0);
340
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_NONE, 0, 0);
341
+
342
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, -3.14159, RC_VALUE_TYPE_FLOAT, 0, -3.14159);
343
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, -3.14159, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFD, 0);
344
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, -3.14159, RC_VALUE_TYPE_SIGNED, (unsigned)-3, 0);
345
+ TEST_PARAMS6(test_typed_value_convert, RC_VALUE_TYPE_FLOAT, 0, -3.14159, RC_VALUE_TYPE_NONE, 0, 0);
346
+ }
347
+
348
+ static void test_typed_value_add(uint8_t type, uint32_t u32, double f32,
349
+ uint8_t amount_type, uint32_t amount_u32, double amount_f32, uint32_t result_u32, double result_f32) {
350
+ rc_typed_value_t value, amount;
351
+
352
+ init_typed_value(&value, type, u32, f32);
353
+ init_typed_value(&amount, amount_type, amount_u32, amount_f32);
354
+
355
+ rc_typed_value_add(&value, &amount);
356
+
357
+ if (result_f32 != 0.0) {
358
+ assert_typed_value(&value, RC_VALUE_TYPE_FLOAT, result_u32, result_f32);
359
+ }
360
+ else if (type == RC_VALUE_TYPE_NONE) {
361
+ assert_typed_value(&value, amount_type, result_u32, result_f32);
362
+ }
363
+ else {
364
+ assert_typed_value(&value, type, result_u32, result_f32);
365
+ }
366
+ }
367
+
368
+ static void test_typed_value_addition() {
369
+ /* no source */
370
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_UNSIGNED, 8, 0.0, 8, 0.0);
371
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_FLOAT, 0, 8.0, 0, 8.0);
372
+
373
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFE, 0.0, 0xFFFFFFFE, 0.0);
374
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_SIGNED, (unsigned)-2, 0.0, (unsigned)-2, 0.0);
375
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_FLOAT, 0, -2.0, 0, -2.0);
376
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0, 0, 0.0);
377
+
378
+ /* unsigned source */
379
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_UNSIGNED, 8, 0.0, 14, 0.0);
380
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_FLOAT, 0, 8.0, 0, 14.0);
381
+
382
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFE, 0.0, 4, 0.0);
383
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_SIGNED, (unsigned)-2, 0.0, 4, 0.0);
384
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_FLOAT, 0, -2.0, 0, 4.0);
385
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0, 6, 0.0);
386
+
387
+ /* signed source */
388
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_UNSIGNED, 2, 0.0, (unsigned)-4, 0.0);
389
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_FLOAT, 0, 2.0, 0, -4.0);
390
+
391
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_UNSIGNED, 8, 0.0, 2, 0.0);
392
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_SIGNED, (unsigned)-2, 0.0, (unsigned)-8, 0.0);
393
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_FLOAT, 0, 2.0, 0, -4.0);
394
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0, (unsigned)-6, 0.0);
395
+
396
+ /* float source (whole numbers) */
397
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_UNSIGNED, 2, 0.0, 0, 8.0);
398
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_FLOAT, 0, 2.0, 0, 8.0);
399
+
400
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFE, 0.0, 0, 4294967300.0);
401
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_SIGNED, (unsigned)-2, 0.0, 0, 4.0);
402
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_FLOAT, 0, -8.0, 0, -2.0);
403
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_NONE, 0, 0.0, 0, 6.0);
404
+
405
+ /* float source (non-whole numbers) */
406
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_UNSIGNED, 2, 0.0, 0, 5.14159);
407
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_SIGNED, (unsigned)-2, 0.0, 0, 1.14159);
408
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_FLOAT, 0, 2.0, 0, 5.14159);
409
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_FLOAT, 0, 6.023, 0, 9.16459);
410
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_FLOAT, 0, -8.0, 0, -4.85841);
411
+ TEST_PARAMS8(test_typed_value_add, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_NONE, 0, 0.0, 0, 3.14159);
412
+ }
413
+
414
+ static void test_typed_value_multiply(char type, uint32_t u32, double f32,
415
+ uint8_t amount_type, uint32_t amount_u32, double amount_f32,
416
+ uint8_t result_type, uint32_t result_u32, double result_f32) {
417
+ rc_typed_value_t value, amount;
418
+
419
+ init_typed_value(&value, type, u32, f32);
420
+ init_typed_value(&amount, amount_type, amount_u32, amount_f32);
421
+
422
+ rc_typed_value_multiply(&value, &amount);
423
+
424
+ assert_typed_value(&value, result_type, result_u32, result_f32);
425
+ }
426
+
427
+ static void test_typed_value_multiplication() {
428
+ /* unsigned source */
429
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_UNSIGNED, 8, 0.0, RC_VALUE_TYPE_UNSIGNED, 48, 0.0);
430
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_FLOAT, 0, 8.0, RC_VALUE_TYPE_FLOAT, 0, 48.0);
431
+
432
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFE, 0.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFF4, 0.0);
433
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_SIGNED, (unsigned)-2, 0.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFF4, 0.0);
434
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_FLOAT, 0, -2.0, RC_VALUE_TYPE_FLOAT, 0, -12.0);
435
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
436
+
437
+ /* signed source */
438
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_UNSIGNED, 2, 0.0, RC_VALUE_TYPE_SIGNED, (unsigned)-12, 0.0);
439
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_FLOAT, 0, 2.0, RC_VALUE_TYPE_FLOAT, 0, -12.0);
440
+
441
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFE, 0.0, RC_VALUE_TYPE_SIGNED, 12, 0.0);
442
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_SIGNED, (unsigned)-2, 0.0, RC_VALUE_TYPE_SIGNED, 12, 0.0);
443
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_FLOAT, 0, 2.0, RC_VALUE_TYPE_FLOAT, 0, -12.0);
444
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
445
+
446
+ /* float source (whole numbers) */
447
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_UNSIGNED, 2, 0.0, RC_VALUE_TYPE_FLOAT, 0, 12.0);
448
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_FLOAT, 0, 2.0, RC_VALUE_TYPE_FLOAT, 0, 12.0);
449
+
450
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFE, 0.0, RC_VALUE_TYPE_FLOAT, 0, 25769803764.0);
451
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_SIGNED, (unsigned)-2, 0.0, RC_VALUE_TYPE_FLOAT, 0, -12.0);
452
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_FLOAT, 0, -8.0, RC_VALUE_TYPE_FLOAT, 0, -48.0);
453
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
454
+
455
+ /* float source (non-whole numbers) */
456
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_UNSIGNED, 2, 0.0, RC_VALUE_TYPE_FLOAT, 0, 6.28318);
457
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_SIGNED, (unsigned)-2, 0.0, RC_VALUE_TYPE_FLOAT, 0, -6.28318);
458
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_FLOAT, 0, 2.0, RC_VALUE_TYPE_FLOAT, 0, 6.28318);
459
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_FLOAT, 0, 6.023, RC_VALUE_TYPE_FLOAT, 0, 18.92179657);
460
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_FLOAT, 0, -8.0, RC_VALUE_TYPE_FLOAT, 0, -25.13272);
461
+ TEST_PARAMS9(test_typed_value_multiply, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
462
+ }
463
+
464
+ static void test_typed_value_divide(uint8_t type, uint32_t u32, double f32,
465
+ uint8_t amount_type, uint32_t amount_u32, double amount_f32,
466
+ uint8_t result_type, uint32_t result_u32, double result_f32) {
467
+ rc_typed_value_t value, amount;
468
+
469
+ init_typed_value(&value, type, u32, f32);
470
+ init_typed_value(&amount, amount_type, amount_u32, amount_f32);
471
+
472
+ rc_typed_value_divide(&value, &amount);
473
+
474
+ assert_typed_value(&value, result_type, result_u32, result_f32);
475
+ }
476
+
477
+ static void test_typed_value_division() {
478
+ /* division by zero */
479
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
480
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
481
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
482
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
483
+
484
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_UNSIGNED, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
485
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_SIGNED, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
486
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_FLOAT, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
487
+
488
+ /* unsigned source */
489
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_UNSIGNED, 2, 0.0, RC_VALUE_TYPE_UNSIGNED, 3, 0.0);
490
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_FLOAT, 0, 2.0, RC_VALUE_TYPE_FLOAT, 0, 3.0);
491
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_FLOAT, 0, 2.5, RC_VALUE_TYPE_FLOAT, 0, 2.4);
492
+
493
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFE, 0.0, RC_VALUE_TYPE_UNSIGNED, 0, 0.0);
494
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_SIGNED, (unsigned)-2, 0.0, RC_VALUE_TYPE_UNSIGNED, 0, 0.0);
495
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_FLOAT, 0, -2.0, RC_VALUE_TYPE_FLOAT, 0, -3.0);
496
+
497
+ /* signed source */
498
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_UNSIGNED, 2, 0.0, RC_VALUE_TYPE_SIGNED, (unsigned)-3, 0.0);
499
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_FLOAT, 0, 2.0, RC_VALUE_TYPE_FLOAT, 0, -3.0);
500
+
501
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFE, 0.0, RC_VALUE_TYPE_SIGNED, 3, 0.0);
502
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_SIGNED, (unsigned)-2, 0.0, RC_VALUE_TYPE_SIGNED, 3, 0.0);
503
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_FLOAT, 0, -2.0, RC_VALUE_TYPE_FLOAT, 0, 3.0);
504
+
505
+ /* float source (whole numbers) */
506
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_UNSIGNED, 2, 0.0, RC_VALUE_TYPE_FLOAT, 0, 3.0);
507
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_FLOAT, 0, 2.0, RC_VALUE_TYPE_FLOAT, 0, 3.0);
508
+
509
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFE, 0.0, RC_VALUE_TYPE_FLOAT, 0, 0.00000000139698386);
510
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_SIGNED, (unsigned)-2, 0.0, RC_VALUE_TYPE_FLOAT, 0, -3.0);
511
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_FLOAT, 0, -8.0, RC_VALUE_TYPE_FLOAT, 0, -0.75);
512
+
513
+ /* float source (non-whole numbers) */
514
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_UNSIGNED, 2, 0.0, RC_VALUE_TYPE_FLOAT, 0, 1.570795);
515
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_SIGNED, (unsigned)-2, 0.0, RC_VALUE_TYPE_FLOAT, 0, -1.570795);
516
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_FLOAT, 0, 2.0, RC_VALUE_TYPE_FLOAT, 0, 1.570795);
517
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_FLOAT, 0, 6.023, RC_VALUE_TYPE_FLOAT, 0, 0.52159887099);
518
+ TEST_PARAMS9(test_typed_value_divide, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_FLOAT, 0, -8.0, RC_VALUE_TYPE_FLOAT, 0, -0.39269875);
519
+ }
520
+
521
+ static void test_typed_value_mod(uint8_t type, uint32_t u32, double f32,
522
+ uint8_t amount_type, uint32_t amount_u32, double amount_f32,
523
+ uint8_t result_type, uint32_t result_u32, double result_f32) {
524
+ rc_typed_value_t value, amount;
525
+
526
+ init_typed_value(&value, type, u32, f32);
527
+ init_typed_value(&amount, amount_type, amount_u32, amount_f32);
528
+
529
+ rc_typed_value_modulus(&value, &amount);
530
+
531
+ assert_typed_value(&value, result_type, result_u32, result_f32);
532
+ }
533
+
534
+ static void test_typed_value_modulus() {
535
+ /* modulus with zero divisor */
536
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
537
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
538
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
539
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
540
+
541
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_UNSIGNED, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
542
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_SIGNED, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
543
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_FLOAT, 0, 0.0, RC_VALUE_TYPE_NONE, 0, 0.0);
544
+
545
+ /* unsigned source */
546
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_UNSIGNED, 4, 0.0, RC_VALUE_TYPE_UNSIGNED, 2, 0.0);
547
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_FLOAT, 0, 4.0, RC_VALUE_TYPE_FLOAT, 0, 2.0);
548
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_FLOAT, 0, 2.25, RC_VALUE_TYPE_FLOAT, 0, 1.5);
549
+
550
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFC, 0.0, RC_VALUE_TYPE_UNSIGNED, 6, 0.0);
551
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_SIGNED, (unsigned)-4, 0.0, RC_VALUE_TYPE_UNSIGNED, 6, 0.0);
552
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_UNSIGNED, 6, 0.0, RC_VALUE_TYPE_FLOAT, 0, -4.0, RC_VALUE_TYPE_FLOAT, 0, 2.0);
553
+
554
+ /* signed source */
555
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_UNSIGNED, 4, 0.0, RC_VALUE_TYPE_SIGNED, (unsigned)-2, 0.0);
556
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_FLOAT, 0, 4.0, RC_VALUE_TYPE_FLOAT, 0, -2.0);
557
+
558
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFC, 0.0, RC_VALUE_TYPE_SIGNED, -2, 0.0);
559
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_SIGNED, (unsigned)-4, 0.0, RC_VALUE_TYPE_SIGNED, -2, 0.0);
560
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_SIGNED, (unsigned)-6, 0.0, RC_VALUE_TYPE_FLOAT, 0, -4.0, RC_VALUE_TYPE_FLOAT, 0, -2.0);
561
+
562
+ /* float source (whole numbers) */
563
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_UNSIGNED, 4, 0.0, RC_VALUE_TYPE_FLOAT, 0, 2.0);
564
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_FLOAT, 0, 4.0, RC_VALUE_TYPE_FLOAT, 0, 2.0);
565
+
566
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFE, 0.0, RC_VALUE_TYPE_FLOAT, 0, 6.0);
567
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_SIGNED, (unsigned)-2, 0.0, RC_VALUE_TYPE_FLOAT, 0, 0.0);
568
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_FLOAT, 0, 6.0, RC_VALUE_TYPE_FLOAT, 0, -5.0, RC_VALUE_TYPE_FLOAT, 0, 1.0);
569
+
570
+ /* float source (non-whole numbers) */
571
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_UNSIGNED, 2, 0.0, RC_VALUE_TYPE_FLOAT, 0, 1.141590);
572
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_SIGNED, (unsigned)-4, 0.0, RC_VALUE_TYPE_FLOAT, 0, 3.141590);
573
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_FLOAT, 0, 2.0, RC_VALUE_TYPE_FLOAT, 0, 1.141590);
574
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_FLOAT, 0, 1.570795, RC_VALUE_TYPE_FLOAT, 0, 0.0);
575
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_FLOAT, 0, 6.023, RC_VALUE_TYPE_FLOAT, 0, 3.141590);
576
+ TEST_PARAMS9(test_typed_value_mod, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_FLOAT, 0, -2.0, RC_VALUE_TYPE_FLOAT, 0, 1.141590);
577
+ }
578
+
579
+ static void test_typed_value_negate(char type, int i32, double f32, char expected_type, signed result_i32, double result_f32) {
580
+ rc_typed_value_t value;
581
+
582
+ init_typed_value(&value, type, (unsigned)i32, f32);
583
+
584
+ rc_typed_value_negate(&value);
585
+
586
+ assert_typed_value(&value, expected_type, (unsigned)result_i32, result_f32);
587
+ }
588
+
589
+ static void test_typed_value_negation() {
590
+ /* unsigned source */
591
+ TEST_PARAMS6(test_typed_value_negate, RC_VALUE_TYPE_UNSIGNED, 0, 0.0, RC_VALUE_TYPE_SIGNED, 0, 0.0);
592
+ TEST_PARAMS6(test_typed_value_negate, RC_VALUE_TYPE_UNSIGNED, 99, 0.0, RC_VALUE_TYPE_SIGNED, -99, 0.0);
593
+ TEST_PARAMS6(test_typed_value_negate, RC_VALUE_TYPE_UNSIGNED, 0xFFFFFFFF, 0.0, RC_VALUE_TYPE_SIGNED, 1, 0.0);
594
+
595
+ /* signed source */
596
+ TEST_PARAMS6(test_typed_value_negate, RC_VALUE_TYPE_SIGNED, 0, 0.0, RC_VALUE_TYPE_SIGNED, 0, 0.0);
597
+ TEST_PARAMS6(test_typed_value_negate, RC_VALUE_TYPE_SIGNED, 99, 0.0, RC_VALUE_TYPE_SIGNED, -99, 0.0);
598
+ TEST_PARAMS6(test_typed_value_negate, RC_VALUE_TYPE_SIGNED, -1, 0.0, RC_VALUE_TYPE_SIGNED, 1, 0.0);
599
+
600
+ /* float source (whole numbers) */
601
+ TEST_PARAMS6(test_typed_value_negate, RC_VALUE_TYPE_FLOAT, 0, 0.0, RC_VALUE_TYPE_FLOAT, 0, 0.0);
602
+ TEST_PARAMS6(test_typed_value_negate, RC_VALUE_TYPE_FLOAT, 0, 99.0, RC_VALUE_TYPE_FLOAT, 0, -99.0);
603
+ TEST_PARAMS6(test_typed_value_negate, RC_VALUE_TYPE_FLOAT, 0, -1.0, RC_VALUE_TYPE_FLOAT, 0, 1.0);
604
+
605
+ /* float source (non-whole numbers) */
606
+ TEST_PARAMS6(test_typed_value_negate, RC_VALUE_TYPE_FLOAT, 0, 0.1, RC_VALUE_TYPE_FLOAT, 0, -0.1);
607
+ TEST_PARAMS6(test_typed_value_negate, RC_VALUE_TYPE_FLOAT, 0, 3.14159, RC_VALUE_TYPE_FLOAT, 0, -3.14159);
608
+ TEST_PARAMS6(test_typed_value_negate, RC_VALUE_TYPE_FLOAT, 0, -2.7, RC_VALUE_TYPE_FLOAT, 0, 2.7);
609
+ }
610
+
611
+ static void test_addhits_float_coercion() {
612
+ rc_value_t* self;
613
+ uint8_t ram[] = { 0x00, 0x06, 0x34, 0xAB, 0x00, 0x00, 0xC0, 0x3F }; /* fF0004 = 1.5 */
614
+ memory_t memory;
615
+ char buffer[2048];
616
+ /* measured(tally(0, (0 + float(4) * 10 - prev(float(4)) * 10) == 1)) */
617
+ const char* memaddr = "A:0_A:fF0004*10_B:dfF0004*10_C:0=1_M:0=1";
618
+ int ret;
619
+
620
+ memory.ram = ram;
621
+ memory.size = sizeof(ram);
622
+
623
+ ret = rc_value_size(memaddr);
624
+ ASSERT_NUM_GREATER_EQUALS(ret, 0);
625
+
626
+ self = rc_parse_value(buffer, memaddr, NULL, 0);
627
+ ASSERT_PTR_NOT_NULL(self);
628
+
629
+ /* The 0+ at the start of the expression changes the accumulator to an integer,
630
+ * so when float(4)*10 is added and prev(float(4))*10 is subtracted, they'll also
631
+ * be converted to integers before they're combined.
632
+ */
633
+
634
+ /* float(4) = 1.5, prev(float(4)) = 0.0. 0+15-0=1 is false => 0 */
635
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
636
+
637
+ /* float(4) = 1.75, prev(float(4)) = 1.5. 0+17-15 => 2 => 2=1 is false => 0 */
638
+ ram[7] = 0x3f; ram[6] = 0xe0;
639
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
640
+
641
+ /* float(4) = 1.82, prev(float(4)) = 1.75. 0+18-17 => 1 => 1=1 is true => 1 */
642
+ ram[6] = 0xe8; ram[5] = 0xf5; ram[4] = 0xc3;
643
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 1);
644
+
645
+ /* float(4) = 2.06, prev(float(4)) = 1.82. 0+20-18 => 2 => 2=1 is false => 1 */
646
+ ram[7] = 0x40; ram[6] = 0x03; ram[5] = 0xd7; ram[4] = 0x0a;
647
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 1);
648
+ }
649
+
650
+ static void test_addhits_float_coercion_remembered() {
651
+ rc_value_t* self;
652
+ uint8_t ram[] = { 0x00, 0x06, 0x34, 0xAB, 0x00, 0x00, 0xC0, 0x3F }; /* fF0004 = 1.5 */
653
+ memory_t memory;
654
+ char buffer[2048];
655
+ /* measured(tally(0, remembered(0 - prev(float(4)) * 10) + (0 + float(4) * 10) == 1)) */
656
+ const char* memaddr = "A:0_B:dfF0004*10_K:0_A:0_A:fF0004*10_C:{recall}=1_M:0=1";
657
+ int ret;
658
+
659
+ memory.ram = ram;
660
+ memory.size = sizeof(ram);
661
+
662
+ ret = rc_value_size(memaddr);
663
+ ASSERT_NUM_GREATER_EQUALS(ret, 0);
664
+
665
+ self = rc_parse_value(buffer, memaddr, NULL, 0);
666
+ ASSERT_PTR_NOT_NULL(self);
667
+
668
+ /* using remember allows for both sides to explicitly be cast to integer before
669
+ * performing the subtraction. */
670
+
671
+ /* float(4) = 1.5, prev(float(4)) = 0.0. 15-0 => 15=1 is false => 0 */
672
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
673
+
674
+ /* float(4) = 1.75, prev(float(4)) = 1.5. 17-15 => 2=1 is false => 0 */
675
+ ram[7] = 0x3f; ram[6] = 0xe0;
676
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 0);
677
+
678
+ /* float(4) = 1.82, prev(float(4)) = 1.75. 18-17 => 1=1 is true => 1 */
679
+ ram[6] = 0xe8; ram[5] = 0xf5; ram[4] = 0xc3;
680
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 1);
681
+
682
+ /* float(4) = 2.06, prev(float(4)) = 1.82. 20-18 => 2=1 is false => 1 */
683
+ ram[7] = 0x40; ram[6] = 0x03; ram[5] = 0xd7; ram[4] = 0x0a;
684
+ ASSERT_NUM_EQUALS(rc_evaluate_value(self, peek, &memory, NULL), 1);
685
+ }
686
+
687
+ void test_value(void) {
688
+ TEST_SUITE_BEGIN();
689
+
690
+ /* ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56}; */
691
+
692
+ /* classic format - supports multipliers, max, inversion */
693
+ TEST_PARAMS2(test_evaluate_value, "V6", 6);
694
+ TEST_PARAMS2(test_evaluate_value, "V6*2", 12);
695
+ TEST_PARAMS2(test_evaluate_value, "V6*0.5", 3);
696
+ TEST_PARAMS2(test_evaluate_value, "V-6", -6);
697
+ TEST_PARAMS2(test_evaluate_value, "V-6*2", -12);
698
+
699
+ TEST_PARAMS2(test_evaluate_value, "0xH0001_0xH0002", 0x12 + 0x34);
700
+ TEST_PARAMS2(test_evaluate_value, "0xH0001*100_0xH0002*0.5_0xL0003", 0x12 * 100 + 0x34 / 2 + 0x0B);
701
+ TEST_PARAMS2(test_evaluate_value, "0xH0001$0xH0002", 0x34);
702
+ TEST_PARAMS2(test_evaluate_value, "0xH0001_0xH0004*3$0xH0002*0xL0003", 0x34 * 0x0B);
703
+ TEST_PARAMS2(test_evaluate_value, "0xH0001_V-20", 0x12 - 20);
704
+ TEST_PARAMS2(test_evaluate_value, "0xH0001_H10", 0x12 + 0x10);
705
+ TEST_PARAMS2(test_evaluate_value, "100-0xH0002", 100 - 0x34);
706
+ TEST_PARAMS2(test_evaluate_value, "0xh0000*-1_99_0xh0001*-100_5900", 4199);
707
+ TEST_PARAMS2(test_evaluate_value, "v5900_0xh0000*-1.0_0xh0001*-100.0", 4100);
708
+ TEST_PARAMS2(test_evaluate_value, "v5900_0xh0000*v-1_0xh0001*v-100", 4100);
709
+
710
+ TEST_PARAMS2(test_evaluate_value, "0xH01*4", 0x12 * 4); /* multiply by constant */
711
+ TEST_PARAMS2(test_evaluate_value, "0xH01*0.5", 0x12 / 2); /* multiply by fraction */
712
+ TEST_PARAMS2(test_evaluate_value, "0xH01/2", 0x12 / 2); /* divide by constant */
713
+ TEST_PARAMS2(test_evaluate_value, "0xH01*0xH02", 0x12 * 0x34); /* multiply by second address */
714
+ TEST_PARAMS2(test_evaluate_value, "0xH01*0xT02", 0); /* multiply by bit */
715
+ TEST_PARAMS2(test_evaluate_value, "0xH01*~0xT02", 0x12); /* multiply by inverse bit */
716
+ TEST_PARAMS2(test_evaluate_value, "0xH01*~0xH02", 0x12 * (0x34 ^ 0xff)); /* multiply by inverse byte */
717
+ TEST_PARAMS2(test_evaluate_value, "0xH0002=0", 0x34); /* legacy format should ignore =0 */
718
+ TEST_PARAMS2(test_evaluate_value, "0xH0000=1_0xH0001=99_0xH0002>200", 0x00 + 0x12 + 0x34); /* legacy format should ignore all comparisons */
719
+
720
+ TEST_PARAMS2(test_evaluate_value, "B0xH01", 12);
721
+ TEST_PARAMS2(test_evaluate_value, "B0x00001", 3412);
722
+ TEST_PARAMS2(test_evaluate_value, "B0xH03", 111); /* 0xAB not really BCD */
723
+ TEST_PARAMS2(test_evaluate_value, "B0xW00", 341200);
724
+
725
+ /* non-comparison measured values just return the value at the address and have no target */
726
+ TEST_PARAMS2(test_measured_value_target, "M:0xH0002", 0);
727
+
728
+ /* hitcount based measured values always have unbounded targets, even if one is specified */
729
+ TEST_PARAMS2(test_measured_value_target, "M:0xH0002!=d0xH0002", (unsigned)-1);
730
+ TEST_PARAMS2(test_measured_value_target, "M:0xH0002!=d0xH0002.99.", (unsigned)-1);
731
+ /* measured values always assumed to be hitcount based - they do not stop/trigger when the condition is met */
732
+ TEST_PARAMS2(test_measured_value_target, "M:0xH0002<100", (unsigned)-1);
733
+
734
+ /* measured format - supports hit counts and combining flags
735
+ * (AddSource, SubSource, AddHits, SubHits, AndNext, OrNext, and AddAddress) */
736
+ TEST_PARAMS2(test_evaluate_value, "M:0xH0002", 0x34);
737
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001_M:0xH0002", 0x12 + 0x34);
738
+ TEST_PARAMS2(test_evaluate_value, "B:0xH0001_M:0xH0002", 0x34 - 0x12);
739
+ TEST_PARAMS2(test_evaluate_value, "C:0xH0000=0_M:0xH0002=52", 2);
740
+ TEST_PARAMS2(test_evaluate_value, "C:0xH0000=0_D:0xH0001=18_M:0xH0002=52", 1);
741
+ TEST_PARAMS2(test_evaluate_value, "N:0xH0000=0_M:0xH0002=52", 1);
742
+ TEST_PARAMS2(test_evaluate_value, "O:0xH0000=0_M:0xH0002=0", 1);
743
+ TEST_PARAMS2(test_evaluate_value, "I:0xH0000_M:0xH0002", 0x34);
744
+
745
+ TEST_PARAMS2(test_evaluate_value, "M:0xH0002*2", 0x34 * 2);
746
+ TEST_PARAMS2(test_evaluate_value, "M:0xH0002/2", 0x34 / 2);
747
+ TEST_PARAMS2(test_evaluate_value, "M:0xH0002%2", 0x34 % 2);
748
+ TEST_PARAMS2(test_evaluate_value, "M:0xH0001%3", 0x12 % 3);
749
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001*2_A:0xH0002*2_M:0", 0x12 * 2 + 0x34 * 2);
750
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001%3_A:0xH0002%4_M:0", 0x12 % 3 + 0x34 % 4);
751
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001*2_M:0xH0002*2", 0x12 * 2 + 0x34 * 2); /* multiplier in final condition */
752
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001/2_M:0xH0002/2", 0x12 / 2 + 0x34 / 2);
753
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001%3_M:0xH0002%4", 0x12 % 3 + 0x34 % 4);
754
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001&15_M:0xH0002&15", (0x12 & 15) + (0x34 & 15));
755
+
756
+ /* measured format does not support alt groups */
757
+ TEST_PARAMS2(test_invalid_value, "M:0xH0002=6SM:0xH0003=6", RC_INVALID_VALUE_FLAG);
758
+ /* does not start with X:, so legacy parser says it's an invalid memory accessor */
759
+ TEST_PARAMS2(test_invalid_value, "SM:0xH0002=6SM:0xH0003=6", RC_INVALID_MEMORY_OPERAND);
760
+
761
+ /* measured format does not support trigger flag */
762
+ TEST_PARAMS2(test_invalid_value, "T:0xH0002=6", RC_INVALID_VALUE_FLAG);
763
+
764
+ /* measured format requires a measured condition */
765
+ TEST_PARAMS2(test_invalid_value, "A:0xH0002_0xH0003>10.99.", RC_INVALID_VALUE_FLAG); /* no flag on condition 2 */
766
+ TEST_PARAMS2(test_invalid_value, "A:0xH0002_A:0xH0003", RC_MISSING_VALUE_MEASURED);
767
+
768
+ /* measured value with float data */
769
+ TEST_PARAMS2(test_evaluate_value, "M:fF0005", 3); /* 3.141592 -> 3 */
770
+ TEST_PARAMS2(test_evaluate_value, "A:fF0005*10_M:0", 31); /* 3.141592 x 10 -> 31.415 -> 31 */
771
+ TEST_PARAMS2(test_evaluate_value, "A:fF0005*f11.2_M:f6.9", 42); /* 3.141592 x 11.2 -> 35.185 + 6.9 -> -> 42.085 -> 42 */
772
+ TEST_PARAMS2(test_evaluate_value, "A:fF0005*f5.555555555555555555555555555555555555555555555556_M:f6.9", 24); /* 3.141592 x 5.555556 -> 17.4532902 + 6.9 -> -> 24.353290 -> 24 */
773
+
774
+ /* delta should initially be 0, so a hit will be tallied */
775
+ TEST_PARAMS2(test_evaluate_value, "M:0xH0002!=d0xH0002", 1);
776
+
777
+ /* division */
778
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001/2_M:0", 9); /* 18/2 = 9 */
779
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001/5_M:0", 3); /* 18/5 = 3 */
780
+ TEST_PARAMS2(test_evaluate_value, "M:0xH0001/5", 3); /* 18/5 = 3 */
781
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0002/0xH0001_M:0", 2); /* 52/18 = 2 */
782
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001/0xH0002_M:0", 0); /* 18/52 = 0 */
783
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001/0xH0001_M:0", 1); /* 18/18 = 1 */
784
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001/0xH0000_M:0", 0); /* 18/0 = 0 */
785
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0000/0xH0000_M:0", 0); /* 0/0 = 0 */
786
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0000/0xH0001_M:0", 0); /* 0/18 = 0 */
787
+
788
+ /* modulus */
789
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001%3_M:0", 0); /* 18%3 = 0 */
790
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001%5_M:0", 3); /* 18%5 = 3 */
791
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001%7_M:0", 4); /* 18%7 = 4 */
792
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0002%0xH0001_M:0", 16); /* 52%18 = 16 */
793
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001%0xH0002_M:0", 18); /* 18%52 = 18 */
794
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001%0xH0001_M:0", 0); /* 18%18 = 0 */
795
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001%0xH0000_M:0", 0); /* 18%0 = 0 */
796
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0000%0xH0000_M:0", 0); /* 0%0 = 0 */
797
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0000%0xH0001_M:0", 0); /* 0%18 = 0 */
798
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0000%0xH0001_M:0", 0); /* 0%18 = 0 */
799
+ TEST_PARAMS2(test_evaluate_value, "A:f5.5%f2.0_M:0", 1) /* 5.5 % 2.0 = 1.5 -> 1 */
800
+ TEST_PARAMS2(test_evaluate_value, "A:f123.7%f5.65_M:0", 5) /* 123.7 % 5.65 = 5.05 -> 5 */
801
+ TEST_PARAMS2(test_evaluate_value, "A:0xH01%f7.5_A:0xH02%f5.5_M:0", 5); /* 18%7.3 = 3.4, 52%5.5=2.5, becomes 3+2=5*/
802
+
803
+ /* addition */
804
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001+3_M:0", 21); /* 18+3 = 21 */
805
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0002+0xH0001_M:0", 70); /* 52+18 = 70 */
806
+ TEST_PARAMS2(test_evaluate_value, "A:fF5+f2_M:0", 5) /* PI + 2.0 = 5.141592 -> 5 */
807
+ TEST_PARAMS2(test_evaluate_value, "A:f5.5+f2.0_M:0", 7) /* 5.5 + 2.0 = 7.5 -> 7 */
808
+ TEST_PARAMS2(test_evaluate_value, "A:f5.5+f2.7_M:0", 8) /* 5.5 + 2.7 = 8.2 -> 8 */
809
+ TEST_PARAMS2(test_evaluate_value, "B:0xH0001+3_M:100", 79) /* 100 - (18+3) = 79 */
810
+ TEST_PARAMS2(test_evaluate_value, "I:0xH0000+3_M:0x0", 0x56AB) /* Add Address (0+3) -> Offset 0. 16-Bit Read @ Byte 3 = 0x56AB */
811
+
812
+ /* subtraction */
813
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0001-3_M:0", 15); /* 18-3 = 15 */
814
+ TEST_PARAMS2(test_evaluate_value, "A:0xH0002-0xH0001_M:0", 34); /* 52-18 = 34 */
815
+ TEST_PARAMS2(test_evaluate_value, "A:fF5-f2_M:0", 1) /* PI - 2.0 = 1.141592 -> 1 */
816
+ TEST_PARAMS2(test_evaluate_value, "A:f5.5-f2.0_M:0", 3) /* 5.5 - 2.0 = 2.5 -> 3 */
817
+ TEST_PARAMS2(test_evaluate_value, "A:f5.5-f2.7_M:0", 2) /* 5.5 - 2.7 = 2.8 -> 2 */
818
+ TEST_PARAMS2(test_evaluate_value, "B:0xH0001-3_M:100",85) /* 100 - (18-3) = 85 */
819
+
820
+ /* rounding */
821
+ TEST_PARAMS2(test_evaluate_value, "0xH03/2_0xH03/2", 0xAA); /* integer division results in rounding */
822
+ TEST_PARAMS2(test_evaluate_value, "0xH03/f2.0_0xH03/f2.0", 0xAB); /* float division does not result in rounding */
823
+ TEST_PARAMS2(test_evaluate_value, "0xH03*0.5_0xH03*0.5", 0xAB); /* float multiplication does not result in rounding */
824
+ TEST_PARAMS2(test_evaluate_value, "A:0xH03/2_A:0xH03/2_M:0", 0xAA); /* integer division results in rounding */
825
+ TEST_PARAMS2(test_evaluate_value, "A:0xH03/f2.0_A:0xH03/f2.0_M:0", 0xAB); /* float division does not result in rounding */
826
+ TEST_PARAMS2(test_evaluate_value, "I:0xH0001-17_M:0x0", 0x3412) /* Add Address (18-17) -> Offset 0. 16-Bit Read @ Byte 1 = 0x3412 */
827
+
828
+ /* using measured_if */
829
+ TEST_PARAMS2(test_evaluate_value, "Q:0xH0001!=0_M:0xH0002", 0x34);
830
+ TEST_PARAMS2(test_evaluate_value, "Q:0xH0001=0_M:0xH0002", 0);
831
+ TEST_PARAMS2(test_evaluate_value, "Q:0xH0001!=0_M:1", 1);
832
+ TEST(test_evaluated_and_next_measured_if_value);
833
+
834
+ /* using accumulator */
835
+ TEST_PARAMS2(test_evaluate_value, "K:0xH01_M:{recall}", 0x12); /* 18-> recall accumulator, Measurement = 18 */
836
+ TEST_PARAMS2(test_evaluate_value, "K:0xH01_K:{recall}*2_M:{recall}", 0x24); /* 18-> recall accumulator, recall accumulator*2 -> recall accumulator, Measurement 18*2 = 36 */
837
+ TEST_PARAMS2(test_evaluate_value, "K:0xH01*0xH02_M:{recall}", 0x3A8); /* 18*52-> recall accumulator, Measurement = 936 */
838
+ TEST_PARAMS2(test_evaluate_value, "A:4_K:0xH01_K:{recall}*2_M:{recall}", 44); /* Chain Addsource into Remember (4 + 18) * 2 = 44 */
839
+ TEST_PARAMS2(test_evaluate_value, "A:4_K:2*8_M:{recall}", 20); /* Chain Addsource into Remember 4 + (2 * 8) = 20 */
840
+ TEST_PARAMS2(test_evaluate_value, "A:4_K:2*8_A:{recall}*2_M:4*{recall}", 120); /* Use remembered value multiple times */
841
+ TEST_PARAMS2(test_evaluate_value, "K:0xH01*2_Q:{recall}<40_P:{recall}=36_M:{recall}", 36); /* Pause happens before recall accumulator is set because remember not part of pause chain. */
842
+ TEST_PARAMS2(test_evaluate_value, "K:0xH01*2_P:{recall}=18_M:{recall}", 36); /* Measures the accumulated value, which was set in the pause pass. */
843
+ TEST_PARAMS2(test_evaluate_value, "K:1_I:{recall}_M:0x02", 0x56AB); /* using recall accumulator as pointer */
844
+ TEST_PARAMS2(test_evaluate_value, "K:1_I:{recall}_K:0x02_M:{recall}", 0x56AB); /* Use recall accumulator as pointer, then store pointed-to data in recall accumulator and measure that */
845
+ TEST_PARAMS2(test_evaluate_value, "K:5_C:{recall}>3_C:{recall}<7_C:{recall}>5_M:0=1", 2); /* with addhits, reusing the recall accumulator in each. */
846
+ TEST_PARAMS2(test_evaluate_value, "K:5_A:1_M:{recall}", 6); /* Add Source onto a read of the recall accumulator as the value */
847
+ TEST_PARAMS2(test_evaluate_value, "K:5_A:1_C:{recall}=6_B:1_C:{recall}=4_M:0=1", 2);
848
+ TEST_PARAMS2(test_evaluate_value, "A:{recall}_M:1", 1); /* Using recall without remember. 0 + 1 = 1*/
849
+ TEST_PARAMS2(test_evaluate_value, "K:{recall}^255_M:{recall}", 255); /* Using recall in first remember. 0x00^0xFF = 0xFF */
850
+ TEST_PARAMS2(test_evaluate_value, "A:1_K:2_M:{recall}", 3); /* Remembered value includes AddSource chain */
851
+
852
+ /* pause and reset affect hit count */
853
+ TEST(test_evaluate_measured_value_with_pause);
854
+ TEST(test_evaluate_measured_value_with_reset);
855
+
856
+ /* overflow - 145406052 * 86 = 125049208332 -> 0x1D1D837E0C, leading 0x1D is truncated off */
857
+ TEST_PARAMS2(test_evaluate_value, "0xX0001*0xH0004", 0x1D837E0C);
858
+
859
+ test_typed_value_conversion();
860
+ test_typed_value_addition();
861
+ test_typed_value_multiplication();
862
+ test_typed_value_division();
863
+ test_typed_value_modulus();
864
+ test_typed_value_negation();
865
+
866
+ test_addhits_float_coercion();
867
+ test_addhits_float_coercion_remembered();
868
+
869
+ TEST_SUITE_END();
870
+ }